xref: /haiku/src/apps/haikudepot/server/AbstractSingleFileServerProcess.cpp (revision dd2a1e350b303b855a50fd64e6cb55618be1ae6a)
1 /*
2  * Copyright 2017-2022, Andrew Lindesay <apl@lindesay.co.nz>.
3  * All rights reserved. Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "AbstractSingleFileServerProcess.h"
8 
9 #include <AutoLocker.h>
10 #include <StopWatch.h>
11 
12 #include "HaikuDepotConstants.h"
13 #include "Logger.h"
14 #include "ServerHelper.h"
15 #include "ServerSettings.h"
16 #include "StorageUtils.h"
17 
18 
19 AbstractSingleFileServerProcess::AbstractSingleFileServerProcess(
20 	uint32 options)
21 	:
22 	AbstractServerProcess(options),
23 	fDownloadDurationSeconds(0.0),
24     fProcessLocalDataDurationSeconds(0.0)
25 {
26 }
27 
28 
29 AbstractSingleFileServerProcess::~AbstractSingleFileServerProcess()
30 {
31 }
32 
33 
34 status_t
35 AbstractSingleFileServerProcess::RunInternal()
36 {
37 	HDINFO("[%s] will fetch data", Name());
38 	BPath localPath;
39 	status_t result = GetLocalPath(localPath);
40 
41 	if (result != B_OK)
42 		return result;
43 
44 	BString urlPathComponent = UrlPathComponent();
45 
46 	if (IsSuccess(result) && HasOption(SERVER_PROCESS_DROP_CACHE))
47 		result = DeleteLocalFile(localPath);
48 
49 	bool hasData = false;
50 	off_t size;
51 
52 	if (IsSuccess(result))
53 		result = StorageUtils::ExistsObject(localPath, &hasData, NULL, &size);
54 
55 	hasData = hasData && size > 0;
56 
57 	if (IsSuccess(result) && ShouldAttemptNetworkDownload(hasData)) {
58 		BStopWatch stopWatch("download", true);
59 		result = DownloadToLocalFileAtomically(
60 			localPath,
61 			ServerSettings::CreateFullUrl(urlPathComponent));
62 		fDownloadDurationSeconds = ((double) stopWatch.ElapsedTime() / 1000000.0);
63 
64 		if (!IsSuccess(result)) {
65 			if (hasData) {
66 				HDINFO("[%s] failed to update data, but have old data "
67 					"anyway so carry on with that", Name());
68 				result = B_OK;
69 			} else
70 				HDERROR("[%s] failed to obtain data", Name());
71 		} else
72 			HDINFO("[%s] did fetch data", Name());
73 	}
74 
75 	if (IsSuccess(result)) {
76 		status_t hasDataResult = StorageUtils::ExistsObject(
77 			localPath, &hasData, NULL, &size);
78 
79 		hasData = hasData && size > 0;
80 
81 		if (hasDataResult == B_OK && !hasData) {
82 			HDINFO("[%s] there is no data to process", Name());
83 			result = HD_ERR_NO_DATA;
84 		}
85 	}
86 
87 	if (IsSuccess(result)) {
88 		HDINFO("[%s] will process data", Name());
89 
90 		BStopWatch stopWatch("process local data", true);
91 		result = ProcessLocalData();
92 		fProcessLocalDataDurationSeconds = ((double) stopWatch.ElapsedTime() / 1000000.0);
93 
94 		switch (result) {
95 			case B_OK:
96 				HDINFO("[%s] did process data", Name());
97 				break;
98 			default:
99 				HDERROR("[%s] failed processing data", Name());
100 				MoveDamagedFileAside(localPath);
101 				break;
102 		}
103 	}
104 
105 	return result;
106 }
107 
108 
109 status_t
110 AbstractSingleFileServerProcess::GetStandardMetaDataPath(BPath& path) const
111 {
112 	return GetLocalPath(path);
113 }
114 
115 
116 BString
117 AbstractSingleFileServerProcess::LogReport()
118 {
119 	BString result;
120 	result.Append(AbstractProcess::LogReport());
121 
122 	AutoLocker<BLocker> locker(&fLock);
123 
124 	if (ProcessState() == PROCESS_COMPLETE) {
125 		BString downloadLogLine;
126 		BString localDataLogLine;
127 		downloadLogLine.SetToFormat("\n - download %6.3f",
128 			fDownloadDurationSeconds);
129 		localDataLogLine.SetToFormat("\n - process local data %6.3f",
130 			fProcessLocalDataDurationSeconds);
131 		result.Append(downloadLogLine);
132 		result.Append(localDataLogLine);
133 	}
134 
135 	return result;
136 }
137