xref: /haiku/src/apps/haikudepot/server/AbstractSingleFileServerProcess.cpp (revision e1c4049fed1047bdb957b0529e1921e97ef94770)
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 			result = HD_ERR_NO_DATA;
83 	}
84 
85 	if (IsSuccess(result)) {
86 		HDINFO("[%s] will process data", Name());
87 
88 		BStopWatch stopWatch("process local data", true);
89 		result = ProcessLocalData();
90 		fProcessLocalDataDurationSeconds = ((double) stopWatch.ElapsedTime() / 1000000.0);
91 
92 		switch (result) {
93 			case B_OK:
94 				HDINFO("[%s] did process data", Name());
95 				break;
96 			default:
97 				HDERROR("[%s] failed processing data", Name());
98 				MoveDamagedFileAside(localPath);
99 				break;
100 		}
101 	}
102 
103 	return result;
104 }
105 
106 
107 status_t
108 AbstractSingleFileServerProcess::GetStandardMetaDataPath(BPath& path) const
109 {
110 	return GetLocalPath(path);
111 }
112 
113 
114 BString
115 AbstractSingleFileServerProcess::LogReport()
116 {
117 	BString result;
118 	result.Append(AbstractProcess::LogReport());
119 
120 	AutoLocker<BLocker> locker(&fLock);
121 
122 	if (ProcessState() == PROCESS_COMPLETE) {
123 		BString downloadLogLine;
124 		BString localDataLogLine;
125 		downloadLogLine.SetToFormat("\n - download %6.3f",
126 			fDownloadDurationSeconds);
127 		localDataLogLine.SetToFormat("\n - process local data %6.3f",
128 			fProcessLocalDataDurationSeconds);
129 		result.Append(downloadLogLine);
130 		result.Append(localDataLogLine);
131 	}
132 
133 	return result;
134 }
135