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
19AbstractSingleFileServerProcess::AbstractSingleFileServerProcess(
20	uint32 options)
21	:
22	AbstractServerProcess(options),
23	fDownloadDurationSeconds(0.0),
24    fProcessLocalDataDurationSeconds(0.0)
25{
26}
27
28
29AbstractSingleFileServerProcess::~AbstractSingleFileServerProcess()
30{
31}
32
33
34status_t
35AbstractSingleFileServerProcess::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
109status_t
110AbstractSingleFileServerProcess::GetStandardMetaDataPath(BPath& path) const
111{
112	return GetLocalPath(path);
113}
114
115
116BString
117AbstractSingleFileServerProcess::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