// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include #include #include #include #include #include #include #include "config/config.h" ZEN_THIRD_PARTY_INCLUDES_START #include ZEN_THIRD_PARTY_INCLUDES_END #include "diag/diagsvcs.h" #include "stats/statsreporter.h" #ifndef ZEN_APP_NAME # define ZEN_APP_NAME "Unreal Zen Storage Server" #endif namespace zen { struct FLLMTag; extern const FLLMTag& GetZenserverTag(); struct ZenStorageServerConfig; class ZenServerBase : public IHttpStatusProvider { ZenServerBase& operator=(ZenServerBase&&) = delete; ZenServerBase(ZenServerBase&&) = delete; public: ZenServerBase(); ~ZenServerBase(); void RequestExit(int ExitCode); void SetIsReadyFunc(std::function&& IsReadyFunc) { m_IsReadyFunc = std::move(IsReadyFunc); } void SetDataRoot(std::filesystem::path Root) { m_DataRoot = Root; } void SetContentRoot(std::filesystem::path Root) { m_ContentRoot = Root; } void SetDedicatedMode(bool State) { m_IsDedicatedMode = State; } void SetTestMode(bool State) { m_TestMode = State; } protected: int Initialize(const ZenServerConfig& ServerOptions, ZenServerState::ZenServerEntry* ServerEntry); void Finalize(); void GetBuildOptions(StringBuilderBase& OutOptions, char Separator = ',') const; void LogSettingsSummary(const ZenServerConfig& ServerConfig); protected: NamedMutex m_ServerMutex; ZenServerState::ZenServerEntry* m_ServerEntry = nullptr; bool m_UseSentry = false; bool m_IsPowerCycle = false; bool m_IsDedicatedMode = false; bool m_TestMode = false; bool m_DebugOptionForcedCrash = false; std::thread m_IoRunner; asio::io_context m_IoContext; void EnsureIoRunner(); enum ServerState { kInitializing, kRunning, kShuttingDown } m_CurrentState = kInitializing; inline void SetNewState(ServerState NewState) { m_CurrentState = NewState; } static std::string_view ToString(ServerState Value); std::function m_IsReadyFunc; void OnReady(); std::filesystem::path m_DataRoot; // Root directory for server state std::filesystem::path m_ContentRoot; // Root directory for frontend content Ref m_Http; std::unique_ptr m_HttpRequestFilter; HttpHealthService m_HealthService; HttpStatusService m_StatusService; // Stats reporting StatsReporter m_StatsReporter; asio::steady_timer m_StatsReportingTimer{m_IoContext}; void EnqueueStatsReportingTimer(); // Process Monitoring void CheckOwnerPid(); bool UpdateProcessMonitor(); void EnqueueProcessMonitorTimer(); ProcessMonitor m_ProcessMonitor; asio::steady_timer m_PidCheckTimer{m_IoContext}; bool m_FoundNoActiveSponsors = false; // Server state exit signaling asio::steady_timer m_StateExitFlagTimer{m_IoContext}; void EnqueueStateExitFlagTimer(); void CheckStateExitFlag(); // SIGINT handling void EnqueueSigIntTimer(); void CheckSigInt(); asio::steady_timer m_SigIntTimer{m_IoContext}; // IHttpStatusProvider virtual void HandleStatusRequest(HttpServerRequest& Request) override; private: void InitializeSecuritySettings(const ZenServerConfig& ServerOptions); }; class ZenServerMain { public: ZenServerMain(ZenServerConfig& ServerOptions); ~ZenServerMain(); int Run(); ZenServerMain(const ZenServerMain&) = delete; ZenServerMain& operator=(const ZenServerMain&) = delete; protected: ZenServerConfig& m_ServerOptions; LockFile m_LockFile; virtual void InitializeLogging(); virtual void DoRun(ZenServerState::ZenServerEntry* Entry) = 0; void NotifyReady(); CbObject MakeLockData(bool IsReady); }; } // namespace zen