/* * Copyright 2017-2025, Andrew Lindesay . * All rights reserved. Distributed under the terms of the MIT License. */ #include "AbstractSingleFileServerProcess.h" #include #include #include "HaikuDepotConstants.h" #include "Logger.h" #include "ServerHelper.h" #include "ServerSettings.h" #include "StorageUtils.h" AbstractSingleFileServerProcess::AbstractSingleFileServerProcess(uint32 options) : AbstractServerProcess(options), fDownloadDurationSeconds(0.0), fProcessLocalDataDurationSeconds(0.0) { } AbstractSingleFileServerProcess::~AbstractSingleFileServerProcess() { } status_t AbstractSingleFileServerProcess::RunInternal() { HDINFO("[%s] will fetch data", Name()); BPath localPath; status_t result = GetLocalPath(localPath); if (result != B_OK) return result; BString urlPathComponent = UrlPathComponent(); if (IsSuccess(result) && HasOption(SERVER_PROCESS_DROP_CACHE)) result = DeleteLocalFile(localPath); bool hasData = false; off_t size; if (IsSuccess(result)) result = StorageUtils::ExistsObject(localPath, &hasData, NULL, &size); hasData = hasData && size > 0; if (IsSuccess(result) && ShouldAttemptNetworkDownload(hasData)) { BStopWatch stopWatch("download", true); result = DownloadToLocalFileAtomically(localPath, ServerSettings::CreateFullUrl(urlPathComponent)); fDownloadDurationSeconds = ((double)stopWatch.ElapsedTime() / 1000000.0); if (!IsSuccess(result)) { if (hasData) { HDINFO("[%s] failed to update data, but have old data anyway so carry on with that", Name()); result = B_OK; } else { HDERROR("[%s] failed to obtain data", Name()); } } else { HDINFO("[%s] did fetch data", Name()); } } if (IsSuccess(result)) { status_t hasDataResult = StorageUtils::ExistsObject(localPath, &hasData, NULL, &size); hasData = hasData && size > 0; if (hasDataResult == B_OK && !hasData) { HDINFO("[%s] there is no data to process", Name()); result = HD_ERR_NO_DATA; } } if (IsSuccess(result)) { HDINFO("[%s] will process data", Name()); BStopWatch stopWatch("process local data", true); result = ProcessLocalData(); fProcessLocalDataDurationSeconds = ((double)stopWatch.ElapsedTime() / 1000000.0); switch (result) { case B_OK: HDINFO("[%s] did process data", Name()); break; default: HDERROR("[%s] failed processing data", Name()); MoveDamagedFileAside(localPath); break; } } return result; } status_t AbstractSingleFileServerProcess::GetStandardMetaDataPath(BPath& path) const { return GetLocalPath(path); } BString AbstractSingleFileServerProcess::LogReport() { BString result; result.Append(AbstractProcess::LogReport()); AutoLocker locker(&fLock); if (ProcessState() == PROCESS_COMPLETE) { BString downloadLogLine; BString localDataLogLine; downloadLogLine.SetToFormat("\n - download %6.3f", fDownloadDurationSeconds); localDataLogLine.SetToFormat("\n - process local data %6.3f", fProcessLocalDataDurationSeconds); result.Append(downloadLogLine); result.Append(localDataLogLine); } return result; }