aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2026-03-19 09:31:01 +0100
committerDan Engelbrecht <[email protected]>2026-03-19 09:31:01 +0100
commit1d59440c6346204bf70550b05c165de361ef81d2 (patch)
treeead2a0d133b154122be5359b364ed0bc353cea4b
parentUpdate libcurl to 8.19.0 (#862) (diff)
downloadzen-de/hub-improvements.tar.xz
zen-de/hub-improvements.zip
add --hub-hydration-target-spec to zen hubde/hub-improvements
-rw-r--r--CHANGELOG.md1
-rw-r--r--src/zenserver/hub/hub.cpp27
-rw-r--r--src/zenserver/hub/hub.h3
-rw-r--r--src/zenserver/hub/hydration.cpp15
-rw-r--r--src/zenserver/hub/hydration.h2
-rw-r--r--src/zenserver/hub/storageserverinstance.cpp10
-rw-r--r--src/zenserver/hub/storageserverinstance.h2
-rw-r--r--src/zenserver/hub/zenhubserver.cpp21
-rw-r--r--src/zenserver/hub/zenhubserver.h1
-rw-r--r--src/zenutil/include/zenutil/zenserverprocess.h2
-rw-r--r--src/zenutil/zenserverprocess.cpp4
11 files changed, 58 insertions, 30 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 362f86fe6..931953b34 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,7 @@
- `--hub-instance-http-threads` Number of HTTP connection threads per instance
- `--hub-instance-corelimit` Limit CPU concurrency per instance
- `--hub-instance-config` Path to Lua config file for instances
+ - `--hub-hydration-target-spec` Specification for the hydration target (e.g. `file://<path>`); defaults to `<data-dir>/servers/hydration_storage`
- Improvement: Console logging is now faster thanks to improved buffering and coloration logic
- Improvement: Added support for CoW block-cloning (used by build download) on Linux (tested with: btrfs/ XFS)
- Improvement: Added full-file CoW copying on macOS (APFS)
diff --git a/src/zenserver/hub/hub.cpp b/src/zenserver/hub/hub.cpp
index 2f3873884..c35fa61e8 100644
--- a/src/zenserver/hub/hub.cpp
+++ b/src/zenserver/hub/hub.cpp
@@ -134,8 +134,16 @@ Hub::Hub(const Configuration& Config,
m_ResourceLimits.DiskUsageBytes = 1000ull * 1024 * 1024 * 1024;
m_ResourceLimits.MemoryUsageBytes = 16ull * 1024 * 1024 * 1024;
- m_FileHydrationPath = m_RunEnvironment.CreateChildDir("hydration_storage");
- ZEN_INFO("using file hydration path: '{}'", m_FileHydrationPath);
+ if (m_Config.HydrationTargetSpecification.empty())
+ {
+ std::filesystem::path FileHydrationPath = m_RunEnvironment.CreateChildDir("hydration_storage");
+ ZEN_INFO("using file hydration path: '{}'", FileHydrationPath);
+ m_HydrationTargetSpecification = fmt::format("file://{}", WideToUtf8(FileHydrationPath.native()));
+ }
+ else
+ {
+ m_HydrationTargetSpecification = m_Config.HydrationTargetSpecification;
+ }
m_HydrationTempPath = m_RunEnvironment.CreateChildDir("hydration_temp");
ZEN_INFO("using hydration temp path: '{}'", m_HydrationTempPath);
@@ -226,15 +234,16 @@ Hub::Provision(std::string_view ModuleId, HubProvisionedInstanceInfo& OutInfo, s
AllocatedPort = m_FreePorts.front();
m_FreePorts.pop_front();
- IsNewInstance = true;
+ IsNewInstance = true;
+
auto NewInstance = std::make_unique<StorageServerInstance>(
m_RunEnvironment,
- StorageServerInstance::Configuration{.BasePort = AllocatedPort,
- .HydrationTempPath = m_HydrationTempPath,
- .FileHydrationPath = m_FileHydrationPath,
- .HttpThreadCount = m_Config.InstanceHttpThreadCount,
- .CoreLimit = m_Config.InstanceCoreLimit,
- .ConfigPath = m_Config.InstanceConfigPath},
+ StorageServerInstance::Configuration{.BasePort = AllocatedPort,
+ .HydrationTempPath = m_HydrationTempPath,
+ .HydrationTargetSpecification = m_HydrationTargetSpecification,
+ .HttpThreadCount = m_Config.InstanceHttpThreadCount,
+ .CoreLimit = m_Config.InstanceCoreLimit,
+ .ConfigPath = m_Config.InstanceConfigPath},
ModuleId);
#if ZEN_PLATFORM_WINDOWS
if (m_JobObject.IsValid())
diff --git a/src/zenserver/hub/hub.h b/src/zenserver/hub/hub.h
index 78be3eda1..7232b99ee 100644
--- a/src/zenserver/hub/hub.h
+++ b/src/zenserver/hub/hub.h
@@ -48,6 +48,7 @@ public:
uint32_t InstanceHttpThreadCount = 0; // Deduce from core count
int InstanceCoreLimit = 0; // Use hardware core count
std::filesystem::path InstanceConfigPath;
+ std::string HydrationTargetSpecification;
};
typedef std::function<void(std::string_view ModuleId, const HubProvisionedInstanceInfo& Info)> ProvisionModuleCallbackFunc;
@@ -113,7 +114,7 @@ private:
ProvisionModuleCallbackFunc m_ProvisionedModuleCallback;
ProvisionModuleCallbackFunc m_DeprovisionedModuleCallback;
- std::filesystem::path m_FileHydrationPath;
+ std::string m_HydrationTargetSpecification;
std::filesystem::path m_HydrationTempPath;
#if ZEN_PLATFORM_WINDOWS
diff --git a/src/zenserver/hub/hydration.cpp b/src/zenserver/hub/hydration.cpp
index 0e78f8545..e56be3934 100644
--- a/src/zenserver/hub/hydration.cpp
+++ b/src/zenserver/hub/hydration.cpp
@@ -10,6 +10,8 @@ namespace zen {
///////////////////////////////////////////////////////////////////////////
+constexpr std::string_view FileHydratorPrefix = "file://";
+
struct FileHydrator : public HydrationStrategyBase
{
virtual void Configure(const HydrationConfig& Config) override;
@@ -26,7 +28,8 @@ FileHydrator::Configure(const HydrationConfig& Config)
{
m_Config = Config;
- std::filesystem::path ConfigPath(Utf8ToWide(m_Config.TargetSpecification));
+ std::filesystem::path ConfigPath(Utf8ToWide(m_Config.TargetSpecification.substr(FileHydratorPrefix.length())));
+ MakeSafeAbsolutePathInPlace(ConfigPath);
if (!std::filesystem::exists(ConfigPath))
{
@@ -112,9 +115,15 @@ FileHydrator::Dehydrate()
}
std::unique_ptr<HydrationStrategyBase>
-CreateFileHydrator()
+CreateHydrator(const HydrationConfig& Config)
{
- return std::make_unique<FileHydrator>();
+ if (StrCaseCompare(Config.TargetSpecification.substr(0, FileHydratorPrefix.length()), FileHydratorPrefix) == 0)
+ {
+ std::unique_ptr<HydrationStrategyBase> Hydrator = std::make_unique<FileHydrator>();
+ Hydrator->Configure(Config);
+ return Hydrator;
+ }
+ throw std::runtime_error(fmt::format("Unknown hydration strategy: {}", Config.TargetSpecification));
}
} // namespace zen
diff --git a/src/zenserver/hub/hydration.h b/src/zenserver/hub/hydration.h
index 95b5cfae0..fb12e7f7c 100644
--- a/src/zenserver/hub/hydration.h
+++ b/src/zenserver/hub/hydration.h
@@ -35,6 +35,6 @@ struct HydrationStrategyBase
virtual void Configure(const HydrationConfig& Config) = 0;
};
-std::unique_ptr<HydrationStrategyBase> CreateFileHydrator();
+std::unique_ptr<HydrationStrategyBase> CreateHydrator(const HydrationConfig& Config);
} // namespace zen
diff --git a/src/zenserver/hub/storageserverinstance.cpp b/src/zenserver/hub/storageserverinstance.cpp
index 8e71e7aca..c54322683 100644
--- a/src/zenserver/hub/storageserverinstance.cpp
+++ b/src/zenserver/hub/storageserverinstance.cpp
@@ -190,11 +190,10 @@ StorageServerInstance::Hydrate()
HydrationConfig Config{.ServerStateDir = m_BaseDir,
.TempDir = m_TempDir,
.ModuleId = m_ModuleId,
- .TargetSpecification = WideToUtf8(m_Config.FileHydrationPath.native())};
+ .TargetSpecification = m_Config.HydrationTargetSpecification};
- std::unique_ptr<HydrationStrategyBase> Hydrator = CreateFileHydrator();
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
- Hydrator->Configure(Config);
Hydrator->Hydrate();
}
@@ -204,11 +203,10 @@ StorageServerInstance::Dehydrate()
HydrationConfig Config{.ServerStateDir = m_BaseDir,
.TempDir = m_TempDir,
.ModuleId = m_ModuleId,
- .TargetSpecification = WideToUtf8(m_Config.FileHydrationPath.native())};
+ .TargetSpecification = m_Config.HydrationTargetSpecification};
- std::unique_ptr<HydrationStrategyBase> Hydrator = CreateFileHydrator();
+ std::unique_ptr<HydrationStrategyBase> Hydrator = CreateHydrator(Config);
- Hydrator->Configure(Config);
Hydrator->Dehydrate();
}
diff --git a/src/zenserver/hub/storageserverinstance.h b/src/zenserver/hub/storageserverinstance.h
index 3b3cae385..9b8aa7ac9 100644
--- a/src/zenserver/hub/storageserverinstance.h
+++ b/src/zenserver/hub/storageserverinstance.h
@@ -25,7 +25,7 @@ public:
{
uint16_t BasePort;
std::filesystem::path HydrationTempPath;
- std::filesystem::path FileHydrationPath;
+ std::string HydrationTargetSpecification;
uint32_t HttpThreadCount = 0; // Deduce from core count
int CoreLimit = 0; // Use hardware core count
std::filesystem::path ConfigPath;
diff --git a/src/zenserver/hub/zenhubserver.cpp b/src/zenserver/hub/zenhubserver.cpp
index b36a0778e..7bced2809 100644
--- a/src/zenserver/hub/zenhubserver.cpp
+++ b/src/zenserver/hub/zenhubserver.cpp
@@ -101,6 +101,14 @@ ZenHubServerConfigurator::AddCliOptions(cxxopts::Options& Options)
cxxopts::value(m_ServerOptions.HubInstanceConfigPath),
"<instance config>");
+ Options.add_option("hub",
+ "",
+ "hub-hydration-target-spec",
+ "Specification for hydration target. 'file://<path>' prefix indicates file storage at <path>. Defaults to "
+ "<data-dir>/servers/hydration_storage",
+ cxxopts::value(m_ServerOptions.HydrationTargetSpecification),
+ "<hydration-target-spec>");
+
#if ZEN_PLATFORM_WINDOWS
Options.add_option("hub",
"",
@@ -272,12 +280,13 @@ ZenHubServer::InitializeServices(const ZenHubServerConfig& ServerConfig)
ZEN_INFO("instantiating Hub");
m_Hub = std::make_unique<Hub>(
- Hub::Configuration{.UseJobObject = ServerConfig.HubUseJobObject,
- .BasePortNumber = ServerConfig.HubBasePortNumber,
- .InstanceLimit = ServerConfig.HubInstanceLimit,
- .InstanceHttpThreadCount = ServerConfig.HubInstanceHttpThreadCount,
- .InstanceCoreLimit = ServerConfig.HubInstanceCoreLimit,
- .InstanceConfigPath = ServerConfig.HubInstanceConfigPath},
+ Hub::Configuration{.UseJobObject = ServerConfig.HubUseJobObject,
+ .BasePortNumber = ServerConfig.HubBasePortNumber,
+ .InstanceLimit = ServerConfig.HubInstanceLimit,
+ .InstanceHttpThreadCount = ServerConfig.HubInstanceHttpThreadCount,
+ .InstanceCoreLimit = ServerConfig.HubInstanceCoreLimit,
+ .InstanceConfigPath = ServerConfig.HubInstanceConfigPath,
+ .HydrationTargetSpecification = ServerConfig.HydrationTargetSpecification},
ZenServerEnvironment(ZenServerEnvironment::Hub,
ServerConfig.DataDir / "hub",
ServerConfig.DataDir / "servers",
diff --git a/src/zenserver/hub/zenhubserver.h b/src/zenserver/hub/zenhubserver.h
index 7e85159f1..15efeaec9 100644
--- a/src/zenserver/hub/zenhubserver.h
+++ b/src/zenserver/hub/zenhubserver.h
@@ -31,6 +31,7 @@ struct ZenHubServerConfig : public ZenServerConfig
uint32_t HubInstanceHttpThreadCount = 0; // Deduce from core count
int HubInstanceCoreLimit = 0; // Use hardware core count
std::filesystem::path HubInstanceConfigPath; // Path to Lua config file
+ std::string HydrationTargetSpecification; // hydration/dehydration target specification
};
class Hub;
diff --git a/src/zenutil/include/zenutil/zenserverprocess.h b/src/zenutil/include/zenutil/zenserverprocess.h
index 101b078e9..5528b766c 100644
--- a/src/zenutil/include/zenutil/zenserverprocess.h
+++ b/src/zenutil/include/zenutil/zenserverprocess.h
@@ -50,7 +50,7 @@ public:
ZenServerEnvironment(EStorageTag, std::filesystem::path ProgramBaseDir);
ZenServerEnvironment(EHubTag,
std::filesystem::path ProgramBaseDir,
- std::filesystem::path TestBaseDir,
+ std::filesystem::path ChildBaseDir,
std::string_view ServerClass = "");
ZenServerEnvironment(ETestTag,
std::filesystem::path ProgramBaseDir,
diff --git a/src/zenutil/zenserverprocess.cpp b/src/zenutil/zenserverprocess.cpp
index e0d99c981..ebce9730e 100644
--- a/src/zenutil/zenserverprocess.cpp
+++ b/src/zenutil/zenserverprocess.cpp
@@ -764,10 +764,10 @@ ZenServerEnvironment::ZenServerEnvironment(EStorageTag, std::filesystem::path Pr
ZenServerEnvironment::ZenServerEnvironment(EHubTag,
std::filesystem::path ProgramBaseDir,
- std::filesystem::path TestBaseDir,
+ std::filesystem::path ChildBaseDir,
std::string_view ServerClass)
{
- InitializeForHub(ProgramBaseDir, TestBaseDir, ServerClass);
+ InitializeForHub(ProgramBaseDir, ChildBaseDir, ServerClass);
}
ZenServerEnvironment::ZenServerEnvironment(ETestTag,