1 /* 2 * Copyright 2021-2023, Andrew Lindesay <apl@lindesay.co.nz>. 3 * All rights reserved. Distributed under the terms of the MIT License. 4 */ 5 #include "IncrementViewCounterProcess.h" 6 7 #include <Catalog.h> 8 9 #include "Logger.h" 10 #include "ServerHelper.h" 11 #include "WebAppInterface.h" 12 13 14 #define ATTEMPTS 3 15 #define SPIN_BETWEEN_ATTEMPTS_DELAY_MI 5 * 1000 * 1000 16 // 5 seconds 17 18 #undef B_TRANSLATION_CONTEXT 19 #define B_TRANSLATION_CONTEXT "IncrementViewCounterProcess" 20 21 22 IncrementViewCounterProcess::IncrementViewCounterProcess( 23 Model* model, const PackageInfoRef& package) 24 : 25 fPackage(package), 26 fModel(model) 27 { 28 fDescription = BString(B_TRANSLATE("Recording view of \"%PackageName%\"")) 29 .ReplaceAll("%PackageName%", fPackage->Name()); 30 } 31 32 33 IncrementViewCounterProcess::~IncrementViewCounterProcess() 34 { 35 } 36 37 38 const char* 39 IncrementViewCounterProcess::Name() const 40 { 41 return "IncrementViewCounterProcess"; 42 } 43 44 45 const char* 46 IncrementViewCounterProcess::Description() const 47 { 48 return fDescription.String(); 49 } 50 51 52 status_t 53 IncrementViewCounterProcess::RunInternal() 54 { 55 if (!ServerHelper::IsNetworkAvailable()) { 56 HDINFO("no network so will not increment view counter"); 57 return B_OK; 58 } 59 60 if (!fPackage.IsSet()) { 61 HDERROR("the package is not present to increment the view counter"); 62 return B_ERROR; 63 } 64 65 DepotInfoRef depot = fModel->DepotForName(fPackage->DepotName()); 66 67 if (!depot.IsSet()) { 68 HDERROR("the package's depot is not present to increment the view " 69 "counter"); 70 return B_ERROR; 71 } 72 73 if (depot->WebAppRepositorySourceCode().IsEmpty()) { 74 HDERROR("cannot increment view counter because depot has no web app " 75 "repository source code"); 76 return B_BAD_DATA; 77 } 78 79 int32 attempts = ATTEMPTS; 80 status_t result = B_OK; 81 82 while (attempts > 0 && !WasStopped()) { 83 BMessage resultEnvelope; 84 WebAppInterface* webAppInterface = fModel->GetWebAppInterface(); 85 result = webAppInterface->IncrementViewCounter(fPackage, depot, resultEnvelope); 86 87 if (result == B_OK) { 88 int32 errorCode = WebAppInterface::ErrorCodeFromResponse(resultEnvelope); 89 switch (errorCode) { 90 case ERROR_CODE_NONE: 91 HDINFO("did increment the view counter for [%s]", 92 fPackage->Name().String()); 93 return result; 94 case ERROR_CODE_OBJECTNOTFOUND: 95 HDINFO("server was not able to find the package [%s]", 96 fPackage->Name().String()); 97 return B_NAME_NOT_FOUND; 98 default: 99 HDERROR("a problem has arisen incrementing the view " 100 "counter for pkg [%s] w/ error code %" B_PRId32, 101 fPackage->Name().String(), errorCode); 102 result = B_ERROR; 103 break; 104 } 105 } else 106 HDERROR("an error has arisen incrementing the view counter"); 107 108 attempts--; 109 _SpinBetweenAttempts(); 110 } 111 112 return result; 113 } 114 115 116 void 117 IncrementViewCounterProcess::_SpinBetweenAttempts() 118 { 119 useconds_t miniSpinDelays = SPIN_BETWEEN_ATTEMPTS_DELAY_MI / 10; 120 for (int32 i = 0; i < 10 && !WasStopped(); i++) 121 usleep(miniSpinDelays); 122 } 123 124