aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/hub/httphubservice.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2026-03-24 18:50:59 +0100
committerGitHub Enterprise <[email protected]>2026-03-24 18:50:59 +0100
commitb730eebe53d1d6827d4b6c320ccfd80566a629a6 (patch)
treed8df23d781b5fb3b1d7bd170fa7d81e2501ab901 /src/zenserver/hub/httphubservice.cpp
parentSubprocess Manager (#889) (diff)
downloadzen-main.tar.xz
zen-main.zip
hub async provision/deprovision/hibernate/wake (#891)HEADmain
- Improvement: Hub provision, deprovision, hibernate, and wake operations are now async. HTTP requests returns 202 Accepted while the operation completes in the background - Improvement: Hub returns 202 Accepted (instead of 409 Conflict) when the same async operation is already in progress for a module - Improvement: Hub returns 200 OK when a requested state transition is already satisfied
Diffstat (limited to 'src/zenserver/hub/httphubservice.cpp')
-rw-r--r--src/zenserver/hub/httphubservice.cpp165
1 files changed, 82 insertions, 83 deletions
diff --git a/src/zenserver/hub/httphubservice.cpp b/src/zenserver/hub/httphubservice.cpp
index 34f4294e4..032a61f08 100644
--- a/src/zenserver/hub/httphubservice.cpp
+++ b/src/zenserver/hub/httphubservice.cpp
@@ -11,6 +11,37 @@
namespace zen {
+namespace {
+ bool HandleFailureResults(HttpServerRequest& Request, const Hub::Response& Resp)
+ {
+ if (Resp.ResponseCode == Hub::EResponseCode::Rejected)
+ {
+ if (Resp.Message.empty())
+ {
+ Request.WriteResponse(HttpResponseCode::Conflict);
+ }
+ else
+ {
+ Request.WriteResponse(HttpResponseCode::Conflict, HttpContentType::kText, Resp.Message);
+ }
+ return true;
+ }
+ if (Resp.ResponseCode == Hub::EResponseCode::NotFound)
+ {
+ if (Resp.Message.empty())
+ {
+ Request.WriteResponse(HttpResponseCode::NotFound);
+ }
+ else
+ {
+ Request.WriteResponse(HttpResponseCode::NotFound, HttpContentType::kText, Resp.Message);
+ }
+ return true;
+ }
+ return false;
+ }
+} // namespace
+
HttpHubService::HttpHubService(Hub& Hub) : m_Hub(Hub)
{
using namespace std::literals;
@@ -83,144 +114,113 @@ HttpHubService::HttpHubService(Hub& Hub) : m_Hub(Hub)
[this](HttpRouterRequest& Req) {
std::string_view ModuleId = Req.GetCapture(1);
- std::string FailureReason = "unknown";
- HttpResponseCode ResponseCode = HttpResponseCode::OK;
-
try
{
HubProvisionedInstanceInfo Info;
- if (m_Hub.Provision(ModuleId, /* out */ Info, /* out */ FailureReason))
- {
- CbObjectWriter Obj;
- Obj << "moduleId" << ModuleId;
- Obj << "baseUri" << Info.BaseUri;
- Obj << "port" << Info.Port;
- Req.ServerRequest().WriteResponse(HttpResponseCode::OK, Obj.Save());
+ Hub::Response Resp = m_Hub.Provision(ModuleId, Info);
- return;
- }
- else
+ if (HandleFailureResults(Req.ServerRequest(), Resp))
{
- ResponseCode = HttpResponseCode::BadRequest;
+ return;
}
+
+ const HttpResponseCode HttpCode =
+ (Resp.ResponseCode == Hub::EResponseCode::Accepted) ? HttpResponseCode::Accepted : HttpResponseCode::OK;
+ CbObjectWriter Obj;
+ Obj << "moduleId" << ModuleId;
+ Obj << "baseUri" << Info.BaseUri;
+ Obj << "port" << Info.Port;
+ return Req.ServerRequest().WriteResponse(HttpCode, Obj.Save());
}
catch (const std::exception& Ex)
{
ZEN_ERROR("Exception while provisioning module '{}': {}", ModuleId, Ex.what());
-
- FailureReason = Ex.what();
- ResponseCode = HttpResponseCode::InternalServerError;
+ throw;
}
-
- Req.ServerRequest().WriteResponse(ResponseCode, HttpContentType::kText, FailureReason);
},
HttpVerb::kPost);
m_Router.RegisterRoute(
"modules/{moduleid}/deprovision",
[this](HttpRouterRequest& Req) {
- std::string_view ModuleId = Req.GetCapture(1);
- std::string FailureReason = "unknown";
+ std::string_view ModuleId = Req.GetCapture(1);
try
{
- if (!m_Hub.Deprovision(std::string(ModuleId), /* out */ FailureReason))
+ Hub::Response Resp = m_Hub.Deprovision(std::string(ModuleId));
+
+ if (HandleFailureResults(Req.ServerRequest(), Resp))
{
- if (FailureReason.empty())
- {
- return Req.ServerRequest().WriteResponse(HttpResponseCode::NotFound);
- }
- else
- {
- return Req.ServerRequest().WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, FailureReason);
- }
+ return;
}
+ const HttpResponseCode HttpCode =
+ (Resp.ResponseCode == Hub::EResponseCode::Accepted) ? HttpResponseCode::Accepted : HttpResponseCode::OK;
CbObjectWriter Obj;
Obj << "moduleId" << ModuleId;
-
- return Req.ServerRequest().WriteResponse(HttpResponseCode::OK, Obj.Save());
+ return Req.ServerRequest().WriteResponse(HttpCode, Obj.Save());
}
catch (const std::exception& Ex)
{
ZEN_ERROR("Exception while deprovisioning module '{}': {}", ModuleId, Ex.what());
-
- FailureReason = Ex.what();
+ throw;
}
-
- Req.ServerRequest().WriteResponse(HttpResponseCode::InternalServerError, HttpContentType::kText, FailureReason);
},
HttpVerb::kPost);
m_Router.RegisterRoute(
"modules/{moduleid}/hibernate",
[this](HttpRouterRequest& Req) {
- std::string_view ModuleId = Req.GetCapture(1);
- std::string FailureReason = "unknown";
+ std::string_view ModuleId = Req.GetCapture(1);
try
{
- if (!m_Hub.Hibernate(std::string(ModuleId), /* out */ FailureReason))
+ Hub::Response Resp = m_Hub.Hibernate(std::string(ModuleId));
+
+ if (HandleFailureResults(Req.ServerRequest(), Resp))
{
- if (FailureReason.empty())
- {
- return Req.ServerRequest().WriteResponse(HttpResponseCode::NotFound);
- }
- else
- {
- return Req.ServerRequest().WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, FailureReason);
- }
+ return;
}
+ const HttpResponseCode HttpCode =
+ (Resp.ResponseCode == Hub::EResponseCode::Accepted) ? HttpResponseCode::Accepted : HttpResponseCode::OK;
CbObjectWriter Obj;
Obj << "moduleId" << ModuleId;
-
- return Req.ServerRequest().WriteResponse(HttpResponseCode::OK, Obj.Save());
+ return Req.ServerRequest().WriteResponse(HttpCode, Obj.Save());
}
catch (const std::exception& Ex)
{
ZEN_ERROR("Exception while hibernating module '{}': {}", ModuleId, Ex.what());
-
- FailureReason = Ex.what();
+ throw;
}
-
- Req.ServerRequest().WriteResponse(HttpResponseCode::InternalServerError, HttpContentType::kText, FailureReason);
},
HttpVerb::kPost);
m_Router.RegisterRoute(
"modules/{moduleid}/wake",
[this](HttpRouterRequest& Req) {
- std::string_view ModuleId = Req.GetCapture(1);
- std::string FailureReason = "unknown";
+ std::string_view ModuleId = Req.GetCapture(1);
try
{
- if (!m_Hub.Wake(std::string(ModuleId), /* out */ FailureReason))
+ Hub::Response Resp = m_Hub.Wake(std::string(ModuleId));
+
+ if (HandleFailureResults(Req.ServerRequest(), Resp))
{
- if (FailureReason.empty())
- {
- return Req.ServerRequest().WriteResponse(HttpResponseCode::NotFound);
- }
- else
- {
- return Req.ServerRequest().WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, FailureReason);
- }
+ return;
}
+ const HttpResponseCode HttpCode =
+ (Resp.ResponseCode == Hub::EResponseCode::Accepted) ? HttpResponseCode::Accepted : HttpResponseCode::OK;
CbObjectWriter Obj;
Obj << "moduleId" << ModuleId;
-
- return Req.ServerRequest().WriteResponse(HttpResponseCode::OK, Obj.Save());
+ return Req.ServerRequest().WriteResponse(HttpCode, Obj.Save());
}
catch (const std::exception& Ex)
{
ZEN_ERROR("Exception while waking module '{}': {}", ModuleId, Ex.what());
-
- FailureReason = Ex.what();
+ throw;
}
-
- Req.ServerRequest().WriteResponse(HttpResponseCode::InternalServerError, HttpContentType::kText, FailureReason);
},
HttpVerb::kPost);
@@ -288,27 +288,27 @@ HttpHubService::HandleModuleDelete(HttpServerRequest& Request, std::string_view
if (InstanceInfo.State == HubInstanceState::Provisioned || InstanceInfo.State == HubInstanceState::Hibernated ||
InstanceInfo.State == HubInstanceState::Crashed)
{
- std::string FailureReason;
try
{
- if (!m_Hub.Deprovision(std::string(ModuleId), FailureReason))
+ Hub::Response Resp = m_Hub.Deprovision(std::string(ModuleId));
+
+ if (HandleFailureResults(Request, Resp))
{
- if (FailureReason.empty())
- {
- Request.WriteResponse(HttpResponseCode::NotFound);
- }
- else
- {
- Request.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, FailureReason);
- }
return;
}
+
+ // TODO: nuke all related storage
+
+ const HttpResponseCode HttpCode =
+ (Resp.ResponseCode == Hub::EResponseCode::Accepted) ? HttpResponseCode::Accepted : HttpResponseCode::OK;
+ CbObjectWriter Obj;
+ Obj << "moduleId" << ModuleId;
+ return Request.WriteResponse(HttpCode, Obj.Save());
}
catch (const std::exception& Ex)
{
ZEN_ERROR("Exception while deprovisioning module '{}': {}", ModuleId, Ex.what());
- Request.WriteResponse(HttpResponseCode::InternalServerError, HttpContentType::kText, Ex.what());
- return;
+ throw;
}
}
@@ -316,7 +316,6 @@ HttpHubService::HandleModuleDelete(HttpServerRequest& Request, std::string_view
CbObjectWriter Obj;
Obj << "moduleId" << ModuleId;
- Obj << "state" << ToString(InstanceInfo.State);
Request.WriteResponse(HttpResponseCode::OK, Obj.Save());
}