// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include #include #include #include #include #include #include #include #include #include namespace zen { /// Client for announcing and maintaining a session on a remote zenserver's /sessions/ endpoint. /// All HTTP I/O runs on a single background worker thread. Public methods enqueue commands /// and return immediately. class SessionsServiceClient { public: struct Options { std::string TargetUrl; // Base URL of the target zenserver (e.g. "http://localhost:8558") std::string AppName; // Application name to register std::string Mode; // Server mode (e.g. "Server", "Compute", "Proxy") std::string Platform; // Client platform; empty = auto-detect via GetRuntimePlatformName() // PID the server uses to track this client's liveness. 0 = don't // report. Auto-filled to GetCurrentProcessId() when TargetUrl looks // local (unix socket, localhost, 127.0.0.1); set explicitly to // override or suppress. uint32_t ClientPid = 0; Oid SessionId = Oid::Zero; // Session ID to register under Oid ParentSessionId = Oid::Zero; // Optional parent session ID // Optional task/action identifier. Use this to associate the session with // a specific unit of work while ParentSessionId links process/session ancestry. Oid JobId = Oid::Zero; HttpClientSettings ClientSettings; // Optional; timeouts are overridden internally (e.g. for unix sockets) }; /// Command sent to the background worker thread. struct SessionCommand { enum class Type : uint8_t { Announce, UpdateMetadata, Remove, Log, FlushLogs, Shutdown }; Type CommandType = Type::Log; CbObject Metadata; // Announce, UpdateMetadata logging::LogLevel LogLevel{}; // Log CompactString LogMessage; // Log }; explicit SessionsServiceClient(Options Opts); ~SessionsServiceClient(); SessionsServiceClient(const SessionsServiceClient&) = delete; SessionsServiceClient& operator=(const SessionsServiceClient&) = delete; /// POST /sessions/{id} — enqueues an announce command (fire-and-forget). void Announce(CbObjectView Metadata = {}); /// PUT /sessions/{id} — enqueues a metadata update command (fire-and-forget). void UpdateMetadata(CbObjectView Metadata = {}); /// DELETE /sessions/{id} — enqueues a remove command (fire-and-forget). void Remove(); /// Create a logging sink that forwards log messages to the session's log endpoint. /// The sink enqueues messages onto this client's worker thread. /// The returned sink can be added to any logger via Logger::AddSink(). logging::SinkPtr CreateLogSink(); const Options& GetOptions() const { return m_Options; } const std::string& GetSessionPath() const { return m_SessionPath; } private: CbObject BuildRequestBody(CbObjectView Metadata) const; void WorkerLoop(); void DoAnnounce(HttpClient& Http, CbObjectView Metadata); void DoUpdateMetadata(HttpClient& Http, CbObjectView Metadata); void DoRemove(HttpClient& Http); void SendLogBatch(HttpClient& Http, const std::string& LogPath, const std::vector& Batch); LoggerRef Log() { return m_Log; } LoggerRef m_Log; Options m_Options; std::string m_SessionPath; // "/sessions/" BlockingQueue m_Queue; std::thread m_WorkerThread; }; } // namespace zen