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