1 /* 2 * Copyright 2021-2022, 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; 81 82 while (attempts > 0 && !WasStopped()) { 83 BMessage resultEnvelope; 84 WebAppInterface& webAppInterface = fModel->GetWebAppInterface(); 85 result = webAppInterface.IncrementViewCounter(fPackage, depot, 86 resultEnvelope); 87 88 if (result == B_OK) { 89 int32 errorCode = webAppInterface.ErrorCodeFromResponse( 90 resultEnvelope); 91 switch (errorCode) { 92 case ERROR_CODE_NONE: 93 HDINFO("did increment the view counter for [%s]", 94 fPackage->Name().String()); 95 return result; 96 case ERROR_CODE_OBJECTNOTFOUND: 97 HDINFO("server was not able to find the package [%s]", 98 fPackage->Name().String()); 99 return B_NAME_NOT_FOUND; 100 default: 101 HDERROR("a problem has arisen incrementing the view " 102 "counter for pkg [%s] w/ error code %" B_PRId32, 103 fPackage->Name().String(), errorCode); 104 result = B_ERROR; 105 break; 106 } 107 } else 108 HDERROR("an error has arisen incrementing the view counter"); 109 110 attempts--; 111 _SpinBetweenAttempts(); 112 } 113 114 return result; 115 } 116 117 118 void 119 IncrementViewCounterProcess::_SpinBetweenAttempts() 120 { 121 useconds_t miniSpinDelays = SPIN_BETWEEN_ATTEMPTS_DELAY_MI / 10; 122 for (int32 i = 0; i < 10 && !WasStopped(); i++) 123 usleep(miniSpinDelays); 124 } 125 126