diff options
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | src/zenserver/hub/hub.cpp | 27 | ||||
| -rw-r--r-- | src/zenserver/hub/hub.h | 3 | ||||
| -rw-r--r-- | src/zenserver/hub/hydration.cpp | 15 | ||||
| -rw-r--r-- | src/zenserver/hub/hydration.h | 2 | ||||
| -rw-r--r-- | src/zenserver/hub/storageserverinstance.cpp | 10 | ||||
| -rw-r--r-- | src/zenserver/hub/storageserverinstance.h | 2 | ||||
| -rw-r--r-- | src/zenserver/hub/zenhubserver.cpp | 21 | ||||
| -rw-r--r-- | src/zenserver/hub/zenhubserver.h | 1 | ||||
| -rw-r--r-- | src/zenutil/include/zenutil/zenserverprocess.h | 2 | ||||
| -rw-r--r-- | src/zenutil/zenserverprocess.cpp | 4 |
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, |