* Copyright 2021-2025, Andrew Lindesay <apl@lindesay.co.nz>.
* All rights reserved. Distributed under the terms of the MIT License.
*/
#include "IncrementViewCounterProcess.h"
#include <Catalog.h>
#include "Logger.h"
#include "PackageUtils.h"
#include "ServerHelper.h"
#include "WebAppInterface.h"
#define ATTEMPTS 3
#define SPIN_BETWEEN_ATTEMPTS_DELAY_MI 5 * 1000 * 1000
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "IncrementViewCounterProcess"
IncrementViewCounterProcess::IncrementViewCounterProcess(Model* model,
const PackageInfoRef& package)
:
fPackage(package),
fModel(model)
{
fDescription = BString(B_TRANSLATE("Recording view of \"%PackageName%\""))
.ReplaceAll("%PackageName%", fPackage->Name());
}
IncrementViewCounterProcess::~IncrementViewCounterProcess()
{
}
const char*
IncrementViewCounterProcess::Name() const
{
return "IncrementViewCounterProcess";
}
const char*
IncrementViewCounterProcess::Description() const
{
return fDescription.String();
}
status_t
IncrementViewCounterProcess::RunInternal()
{
if (!ServerHelper::IsNetworkAvailable()) {
HDINFO("no network so will not increment view counter");
return B_OK;
}
BString depotName = PackageUtils::DepotName(fPackage);
DepotInfoRef depot = fModel->DepotForName(depotName);
if (!depot.IsSet()) {
HDERROR("the package's depot is not present to increment the view counter");
return B_ERROR;
}
if (depot->WebAppRepositorySourceCode().IsEmpty()) {
HDERROR(
"cannot increment view counter because depot has no web app repository source code");
return B_BAD_DATA;
}
int32 attempts = ATTEMPTS;
status_t result = B_OK;
while (attempts > 0 && !WasStopped() && ServerHelper::IsNetworkAvailable()) {
BMessage resultEnvelope;
WebAppInterfaceRef webApp = fModel->WebApp();
result = webApp->IncrementViewCounter(fPackage, depot, resultEnvelope);
if (result == B_OK) {
int32 errorCode = WebAppInterface::ErrorCodeFromResponse(resultEnvelope);
switch (errorCode) {
case ERROR_CODE_NONE:
HDINFO("did increment the view counter for [%s]", fPackage->Name().String());
return result;
case ERROR_CODE_OBJECTNOTFOUND:
HDINFO("server was not able to find the package [%s]",
fPackage->Name().String());
return B_NAME_NOT_FOUND;
default:
HDERROR("a problem has arisen incrementing the view "
"counter for pkg [%s] w/ error code %" B_PRId32,
fPackage->Name().String(), errorCode);
result = B_ERROR;
break;
}
} else {
HDERROR("an error has arisen incrementing the view counter");
}
attempts--;
_SpinBetweenAttempts();
}
return result;
}
void
IncrementViewCounterProcess::_SpinBetweenAttempts()
{
useconds_t miniSpinDelays = SPIN_BETWEEN_ATTEMPTS_DELAY_MI / 10;
for (int32 i = 0; i < 10 && !WasStopped(); i++)
usleep(miniSpinDelays);
}