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 22IncrementViewCounterProcess::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 33IncrementViewCounterProcess::~IncrementViewCounterProcess() 34{ 35} 36 37 38const char* 39IncrementViewCounterProcess::Name() const 40{ 41 return "IncrementViewCounterProcess"; 42} 43 44 45const char* 46IncrementViewCounterProcess::Description() const 47{ 48 return fDescription.String(); 49} 50 51 52status_t 53IncrementViewCounterProcess::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 116void 117IncrementViewCounterProcess::_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