diff options
| author | Stefan Boberg <[email protected]> | 2026-03-13 09:24:59 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2026-03-13 09:24:59 +0100 |
| commit | ef586f5930ac761f8e8e18cde2ebd5248efeaa4a (patch) | |
| tree | be6c7d3e11f9261c1d03d646bc579ac0d27452d7 /src/zen/zen.cpp | |
| parent | Switch httpclient default back-end over to libcurl (#832) (diff) | |
| download | archived-zen-ef586f5930ac761f8e8e18cde2ebd5248efeaa4a.tar.xz archived-zen-ef586f5930ac761f8e8e18cde2ebd5248efeaa4a.zip | |
Unix Domain Socket auto discovery (#833)
This PR adds end-to-end Unix domain socket (UDS) support, allowing zen CLI to discover and connect to UDS-only servers automatically.
- **`unix://` URI scheme in zen CLI**: The `-u` / `--hosturl` option now accepts `unix:///path/to/socket` to connect to a zenserver via a Unix domain socket instead of TCP.
- **Per-instance shared memory for extended server info**: Each zenserver instance now publishes a small shared memory section (keyed by SessionId) containing per-instance data that doesn't fit in the fixed-size ZenServerEntry -- starting with the UDS socket path. This is a 4KB pagefile-backed section on Windows (`Global\ZenInstance_{sessionid}`) and a POSIX shared memory object on Linux/Mac (`/UnrealEngineZen_{sessionid}`).
- **Client-side auto-discovery of UDS servers**: `zen info`, `zen status`, etc. now automatically discover and prefer UDS connections when a server publishes a socket path. Servers running with `--no-network` (UDS-only) are no longer invisible to the CLI.
- **`kNoNetwork` flag in ZenServerEntry**: Servers started with `--no-network` advertise this in their shared state entry. Clients skip TCP fallback for these servers, and display commands (`ps`, `status`, `top`) show `-` instead of a port number to indicate TCP is not available.
Diffstat (limited to 'src/zen/zen.cpp')
| -rw-r--r-- | src/zen/zen.cpp | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/src/zen/zen.cpp b/src/zen/zen.cpp index 10e3a85fe..86154c291 100644 --- a/src/zen/zen.cpp +++ b/src/zen/zen.cpp @@ -369,9 +369,31 @@ GetReturnCodeFromHttpResult(const HttpClientError& Ex) } } +bool +ZenCmdBase::IsUnixSocketSpec(std::string_view Spec) +{ + return Spec.starts_with("unix://"); +} + +HttpClient +ZenCmdBase::CreateHttpClient(const std::string& HostSpec, HttpClientSettings Settings) +{ + if (IsUnixSocketSpec(HostSpec)) + { + Settings.UnixSocketPath = HostSpec.substr(7); // strip "unix://" + return HttpClient("http://localhost", Settings); + } + return HttpClient(HostSpec, Settings); +} + std::string ZenCmdBase::ResolveTargetHostSpec(const std::string& InHostSpec, uint16_t& OutEffectivePort) { + if (IsUnixSocketSpec(InHostSpec)) + { + return InHostSpec; // pass through as-is; parsed later in CreateHttpClient + } + if (InHostSpec.empty()) { // If no host is specified then look to see if we have an instance @@ -386,8 +408,30 @@ ZenCmdBase::ResolveTargetHostSpec(const std::string& InHostSpec, uint16_t& OutEf Servers.Snapshot([&](const zen::ZenServerState::ZenServerEntry& Entry) { if (ResolvedSpec.empty()) { - ResolvedSpec = fmt::format("http://localhost:{}", Entry.EffectiveListenPort.load()); OutEffectivePort = Entry.EffectiveListenPort; + + // Check for per-instance info (e.g. UDS path) + if (Entry.HasInstanceInfo()) + { + ZenServerInstanceInfo Info; + if (Info.OpenReadOnly(Entry.GetSessionId())) + { + InstanceInfoData Data = Info.Read(); + if (!Data.UnixSocketPath.empty()) + { + ResolvedSpec = "unix://" + PathToUtf8(Data.UnixSocketPath); + return; + } + } + } + + // Skip servers with --no-network since TCP is not reachable + if (Entry.IsNoNetwork()) + { + return; + } + + ResolvedSpec = fmt::format("http://localhost:{}", Entry.EffectiveListenPort.load()); } }); |