aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/hub/hubservice.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2026-02-28 15:36:50 +0100
committerGitHub Enterprise <[email protected]>2026-02-28 15:36:50 +0100
commitf796ee9e650d5f73844f862ed51a6de6bb33c219 (patch)
tree18f09f4f1567d383058e8648d18dc229b79e08bd /src/zenserver/hub/hubservice.cpp
parenttest running / reporting improvements (#797) (diff)
downloadzen-main.tar.xz
zen-main.zip
subprocess tracking using Jobs on Windows/hub (#796)HEADmain
This change introduces job object support on Windows to be able to more accurately track and limit resource usage on storage instances created by the hub service. It also ensures that all child instances can be torn down reliably on exit. Also made it so hub tests no longer pop up console windows while running.
Diffstat (limited to 'src/zenserver/hub/hubservice.cpp')
-rw-r--r--src/zenserver/hub/hubservice.cpp49
1 files changed, 46 insertions, 3 deletions
diff --git a/src/zenserver/hub/hubservice.cpp b/src/zenserver/hub/hubservice.cpp
index a00446a75..bf0e294c5 100644
--- a/src/zenserver/hub/hubservice.cpp
+++ b/src/zenserver/hub/hubservice.cpp
@@ -8,6 +8,7 @@
#include <zencore/filesystem.h>
#include <zencore/fmtutils.h>
#include <zencore/logging.h>
+#include <zencore/process.h>
#include <zencore/scopeguard.h>
#include <zencore/system.h>
#include <zenutil/zenserverprocess.h>
@@ -150,6 +151,10 @@ struct StorageServerInstance
inline uint16_t GetBasePort() const { return m_ServerInstance.GetBasePort(); }
+#if ZEN_PLATFORM_WINDOWS
+ void SetJobObject(JobObject* InJobObject) { m_JobObject = InJobObject; }
+#endif
+
private:
void WakeLocked();
RwLock m_Lock;
@@ -161,6 +166,9 @@ private:
std::filesystem::path m_TempDir;
std::filesystem::path m_HydrationPath;
ResourceMetrics m_ResourceMetrics;
+#if ZEN_PLATFORM_WINDOWS
+ JobObject* m_JobObject = nullptr;
+#endif
void SpawnServerProcess();
@@ -191,6 +199,9 @@ StorageServerInstance::SpawnServerProcess()
m_ServerInstance.SetServerExecutablePath(GetRunningExecutablePath());
m_ServerInstance.SetDataDir(m_BaseDir);
+#if ZEN_PLATFORM_WINDOWS
+ m_ServerInstance.SetJobObject(m_JobObject);
+#endif
const uint16_t BasePort = m_ServerInstance.SpawnServerAndWaitUntilReady();
ZEN_DEBUG("Storage server instance for module '{}' started, listening on port {}", m_ModuleId, BasePort);
@@ -380,6 +391,21 @@ struct HttpHubService::Impl
// flexibility, and to allow running multiple hubs on the same host if
// necessary.
m_RunEnvironment.SetNextPortNumber(21000);
+
+#if ZEN_PLATFORM_WINDOWS
+ if (m_UseJobObject)
+ {
+ m_JobObject.Initialize();
+ if (m_JobObject.IsValid())
+ {
+ ZEN_INFO("Job object initialized for hub service child process management");
+ }
+ else
+ {
+ ZEN_WARN("Failed to initialize job object; child processes will not be auto-terminated on hub crash");
+ }
+ }
+#endif
}
void Cleanup()
@@ -422,6 +448,12 @@ struct HttpHubService::Impl
IsNewInstance = true;
auto NewInstance =
std::make_unique<StorageServerInstance>(m_RunEnvironment, ModuleId, m_FileHydrationPath, m_HydrationTempPath);
+#if ZEN_PLATFORM_WINDOWS
+ if (m_JobObject.IsValid())
+ {
+ NewInstance->SetJobObject(&m_JobObject);
+ }
+#endif
Instance = NewInstance.get();
m_Instances.emplace(std::string(ModuleId), std::move(NewInstance));
@@ -579,10 +611,15 @@ struct HttpHubService::Impl
inline int GetInstanceLimit() { return m_InstanceLimit; }
inline int GetMaxInstanceCount() { return m_MaxInstanceCount; }
+ bool m_UseJobObject = true;
+
private:
- ZenServerEnvironment m_RunEnvironment;
- std::filesystem::path m_FileHydrationPath;
- std::filesystem::path m_HydrationTempPath;
+ ZenServerEnvironment m_RunEnvironment;
+ std::filesystem::path m_FileHydrationPath;
+ std::filesystem::path m_HydrationTempPath;
+#if ZEN_PLATFORM_WINDOWS
+ JobObject m_JobObject;
+#endif
RwLock m_Lock;
std::unordered_map<std::string, std::unique_ptr<StorageServerInstance>> m_Instances;
std::unordered_set<std::string> m_DeprovisioningModules;
@@ -817,6 +854,12 @@ HttpHubService::~HttpHubService()
{
}
+void
+HttpHubService::SetUseJobObject(bool Enable)
+{
+ m_Impl->m_UseJobObject = Enable;
+}
+
const char*
HttpHubService::BaseUri() const
{