aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zenhttp/httpasio.cpp12
-rw-r--r--zenserver/compute/apply.cpp31
-rw-r--r--zenserver/compute/apply.h2
-rw-r--r--zenserver/upstream/upstreamapply.cpp56
4 files changed, 66 insertions, 35 deletions
diff --git a/zenhttp/httpasio.cpp b/zenhttp/httpasio.cpp
index 9a23a25ef..7ee7193d1 100644
--- a/zenhttp/httpasio.cpp
+++ b/zenhttp/httpasio.cpp
@@ -500,7 +500,17 @@ HttpServerConnection::HandleRequest()
if (!HandlePackageOffers(*Service, Request, m_PackageHandler))
{
- Service->HandleRequest(Request);
+ try
+ {
+ Service->HandleRequest(Request);
+ }
+ catch (std::exception& ex)
+ {
+ ZEN_ERROR("Caught exception while handling request: '{}'", ex.what());
+
+ Request.WriteResponse(HttpResponseCode::InternalServerError, HttpContentType::kText, ex.what());
+ }
+
}
if (std::unique_ptr<HttpResponse> Response = std::move(Request.m_Response))
diff --git a/zenserver/compute/apply.cpp b/zenserver/compute/apply.cpp
index 1f18b054f..ae4dd4528 100644
--- a/zenserver/compute/apply.cpp
+++ b/zenserver/compute/apply.cpp
@@ -578,9 +578,13 @@ HttpFunctionService::HttpFunctionService(CasStore& Store, CidStore& InCidStore,
if (NeedList.empty())
{
// We already have everything
+ CbObject Output;
+ HttpResponseCode ResponseCode = ExecActionUpstream(Worker, RequestObject, Output);
- CbObject Output = ExecActionUpstream(Worker, RequestObject);
-
+ if (ResponseCode != HttpResponseCode::OK)
+ {
+ return HttpReq.WriteResponse(ResponseCode);
+ }
return HttpReq.WriteResponse(HttpResponseCode::OK, Output);
}
@@ -638,8 +642,13 @@ HttpFunctionService::HttpFunctionService(CasStore& Store, CidStore& InCidStore,
zen::NiceBytes(TotalNewBytes),
NewAttachmentCount);
- CbObject Output = ExecActionUpstream(Worker, ActionObj);
+ CbObject Output;
+ HttpResponseCode ResponseCode = ExecActionUpstream(Worker, ActionObj, Output);
+ if (ResponseCode != HttpResponseCode::OK)
+ {
+ return HttpReq.WriteResponse(ResponseCode);
+ }
return HttpReq.WriteResponse(HttpResponseCode::OK, Output);
}
break;
@@ -881,8 +890,8 @@ HttpFunctionService::ExecAction(const WorkerDesc& Worker, CbObject Action)
return OutputPackage;
}
-CbObject
-HttpFunctionService::ExecActionUpstream(const WorkerDesc& Worker, CbObject Action)
+HttpResponseCode
+HttpFunctionService::ExecActionUpstream(const WorkerDesc& Worker, CbObject Action, CbObject& Object)
{
const IoHash WorkerId = Worker.Descriptor.GetHash();
const IoHash ActionId = Action.GetHash();
@@ -895,14 +904,19 @@ HttpFunctionService::ExecActionUpstream(const WorkerDesc& Worker, CbObject Actio
if (!EnqueueResult.Success)
{
- throw std::runtime_error("Error enqueuing upstream task");
+ ZEN_ERROR(
+ "Error enqueuing upstream Action {}/{}",
+ WorkerId.ToHexString(),
+ ActionId.ToHexString());
+ return HttpResponseCode::InternalServerError;
}
CbObjectWriter Writer;
Writer.AddHash("worker", WorkerId);
Writer.AddHash("action", ActionId);
- return std::move(Writer.Save());
+ Object = std::move(Writer.Save());
+ return HttpResponseCode::OK;
}
HttpResponseCode
@@ -932,8 +946,7 @@ HttpFunctionService::ExecActionUpstreamResult(const IoHash& WorkerId, const IoHa
Completed.Error.Reason,
Completed.Error.ErrorCode);
- throw std::runtime_error(
- "Action {}/{} failed"_format(WorkerId.ToHexString(), ActionId.ToHexString()).c_str());
+ return HttpResponseCode::InternalServerError;
}
ZEN_INFO("Action {}/{} completed with {} attachments ({} compressed, {} uncompressed)",
diff --git a/zenserver/compute/apply.h b/zenserver/compute/apply.h
index 15cda4750..0d6edf119 100644
--- a/zenserver/compute/apply.h
+++ b/zenserver/compute/apply.h
@@ -46,7 +46,7 @@ private:
[[nodiscard]] std::filesystem::path CreateNewSandbox();
[[nodiscard]] CbPackage ExecAction(const WorkerDesc& Worker, CbObject Action);
- [[nodiscard]] CbObject ExecActionUpstream(const WorkerDesc& Worker, CbObject Action);
+ [[nodiscard]] HttpResponseCode ExecActionUpstream(const WorkerDesc& Worker, CbObject Action, CbObject& Object);
[[nodiscard]] HttpResponseCode ExecActionUpstreamResult(const IoHash& WorkerId, const IoHash& ActionId, CbPackage& Package);
RwLock m_WorkerLock;
diff --git a/zenserver/upstream/upstreamapply.cpp b/zenserver/upstream/upstreamapply.cpp
index 1779099ff..e6e54428c 100644
--- a/zenserver/upstream/upstreamapply.cpp
+++ b/zenserver/upstream/upstreamapply.cpp
@@ -37,6 +37,9 @@ namespace zen {
using namespace std::literals;
+static const IoBuffer EmptyBuffer;
+static const IoHash EmptyBufferId = IoHash::HashBuffer(EmptyBuffer);
+
namespace detail {
class HordeUpstreamApplyEndpoint final : public UpstreamApplyEndpoint
@@ -109,7 +112,8 @@ namespace detail {
ElapsedSeconds += Result.ElapsedSeconds;
if (!Result.Success)
{
- return {.Error{.ErrorCode = Result.ErrorCode, .Reason = std::move(Result.Reason)},
+ return {.Error{.ErrorCode = Result.ErrorCode ? Result.ErrorCode : -1,
+ .Reason = !Result.Reason.empty() ? std::move(Result.Reason) : "Failed to upload blobs"},
.Bytes = Bytes,
.ElapsedSeconds = ElapsedSeconds};
}
@@ -122,7 +126,8 @@ namespace detail {
ElapsedSeconds += Result.ElapsedSeconds;
if (!Result.Success)
{
- return {.Error{.ErrorCode = Result.ErrorCode, .Reason = std::move(Result.Reason)},
+ return {.Error{.ErrorCode = Result.ErrorCode ? Result.ErrorCode : -1,
+ .Reason = !Result.Reason.empty() ? std::move(Result.Reason) : "Failed to upload objects"},
.Bytes = Bytes,
.ElapsedSeconds = ElapsedSeconds};
}
@@ -146,7 +151,8 @@ namespace detail {
m_PendingTasks.erase(UpstreamData.TaskId);
}
- return {.Error{.ErrorCode = Result.ErrorCode, .Reason = std::move(Result.Reason)},
+ return {.Error{.ErrorCode = Result.ErrorCode ? Result.ErrorCode : -1,
+ .Reason = !Result.Reason.empty() ? std::move(Result.Reason) : "Failed to post compute task"},
.Bytes = Bytes,
.ElapsedSeconds = ElapsedSeconds};
}
@@ -457,13 +463,6 @@ namespace detail {
Bytes += ObjectTreeResult.Bytes;
ElapsedSeconds += ObjectTreeResult.ElapsedSeconds;
- if (ObjectTreeResult.ErrorCode != 0)
- {
- return {.Error{.ErrorCode = ObjectTreeResult.ErrorCode, .Reason = std::move(ObjectTreeResult.Reason)},
- .Bytes = Bytes,
- .ElapsedSeconds = ElapsedSeconds};
- }
-
if (!ObjectTreeResult.Success)
{
return {.Error{.ErrorCode = -1, .Reason = "Failed to get result object data"},
@@ -589,7 +588,9 @@ namespace detail {
{
return {.Error{.ErrorCode = ExitCode, .Reason = "Build.output file not found in task results"},
.Bytes = Bytes,
- .ElapsedSeconds = ElapsedSeconds};
+ .ElapsedSeconds = ElapsedSeconds,
+ .StdOut = std::move(StdOut),
+ .StdErr = std::move(StdErr)};
}
// Get Output directory node
@@ -608,7 +609,9 @@ namespace detail {
{
return {.Error{.ErrorCode = ExitCode, .Reason = "Outputs directory not found in task results"},
.Bytes = Bytes,
- .ElapsedSeconds = ElapsedSeconds};
+ .ElapsedSeconds = ElapsedSeconds,
+ .StdOut = std::move(StdOut),
+ .StdErr = std::move(StdErr)};
}
// load build.output as CbObject
@@ -683,7 +686,9 @@ namespace detail {
{
return {.Error{.ErrorCode = -1, .Reason = "Failed to get result object attachment data"},
.Bytes = Bytes,
- .ElapsedSeconds = ElapsedSeconds};
+ .ElapsedSeconds = ElapsedSeconds,
+ .StdOut = std::move(StdOut),
+ .StdErr = std::move(StdErr)};
}
OutputPackage.SetObject(BuildOutputObject);
@@ -705,6 +710,8 @@ namespace detail {
[[nodiscard]] bool ProcessApplyKey(const UpstreamApplyRecord& ApplyRecord, UpstreamData& Data)
{
+ using namespace fmt::literals;
+
std::string ExecutablePath;
std::map<std::string, std::string> Environment;
std::set<std::filesystem::path> InputFiles;
@@ -736,6 +743,15 @@ namespace detail {
}
}
+ for (auto& It : ApplyRecord.WorkerDescriptor["dirs"sv])
+ {
+ std::string_view Directory = It.AsString();
+ std::string DummyFile = "{}/.zen_empty_file"_format(Directory);
+ InputFiles.insert(DummyFile);
+ Data.Blobs[EmptyBufferId] = EmptyBuffer;
+ InputFileHashes[DummyFile] = EmptyBufferId;
+ }
+
for (auto& It : ApplyRecord.WorkerDescriptor["environment"sv])
{
std::string_view Env = It.AsString();
@@ -810,18 +826,10 @@ namespace detail {
bool Exclusive = ApplyRecord.WorkerDescriptor["exclusive"sv].AsBool();
// TODO: Remove override when Horde accepts the UE style Host Platforms (Win64, Linux, Mac)
- std::string Condition;
- if (HostPlatform == "Win64" || HostPlatform == "Windows")
- {
- Condition = "OSFamily == 'Windows' && Pool == 'Win-RemoteExec'";
- }
- else if (HostPlatform == "Mac")
- {
- Condition = "OSFamily == 'MacOS'";
- }
- else
+ std::string Condition = "Platform == '{}'"_format(HostPlatform);
+ if (HostPlatform == "Win64")
{
- Condition = "OSFamily == '{}'"_format(HostPlatform);
+ Condition += " && Pool == 'Win-RemoteExec'";
}
std::map<std::string_view, int64_t> Resources;