xref: /haiku/src/apps/haikudepot/server/IncrementViewCounterProcess.cpp (revision 1978089f7cec856677e46204e992c7273d70b9af)
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