mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-10 16:04:04 +00:00
fix(server): force line-buffered stdout so a detached server actually logs
Godot's stdout is fully (block) buffered whenever it isn't attached to a TTY -- true of every real deployment path this repo documents: 'docker run -d' (Docker's log driver presents a pipe), a plain 'docker run' without -d, and systemd's journal capture (also a pipe). Confirmed directly, not from the existing gotcha note alone: a real 'docker run -d' container sat for 20+ seconds with 'docker logs' showing nothing at all -- not even the startup line -- while the process was confirmed alive and running (ps aux inside the container). 'docker stop' then killed it via SIGTERM (Godot has no SIGTERM hook) without ever flushing that buffered output, losing it permanently rather than merely delaying it. This affects the already-shipped community server path today, not just the not-yet-built Agones fleet path multiplayer-next.md's task 8.28 gotcha originally flagged this for -- SERVER.md's Docker AND native-systemd instructions both route through this exact launcher script, and journald's capture has the same non-TTY-pipe buffering problem docker logs does. Wrap the exec in 'stdbuf -oL -eL' (LD_PRELOAD-based line buffering, touches no binary) when available, falling back to the unwrapped exec otherwise so a minimal image without GNU coreutils still starts. Re-verified the same failing scenario against the actual launcher script in a real image: the startup line now appears within 3s of a genuinely detached 'docker run -d'. Re-ran the full make verify-phase6 gate end to end afterward to confirm no regression: both arenas rotated, both clients observed both goals, clean teardown.
This commit is contained in:
@@ -3,4 +3,21 @@
|
||||
# is baked into the dedicated artifact during the Docker export stage.
|
||||
set -eu
|
||||
|
||||
# Godot's stdout is fully (block) buffered rather than line-buffered whenever
|
||||
# it isn't attached to a TTY -- true of every real deployment of this script:
|
||||
# `docker run -d` (Docker's log driver presents a pipe, not a TTY), a plain
|
||||
# `docker run` even without -d, and systemd's journal capture (also a pipe).
|
||||
# Verified directly: a `docker run -d` container sat for 20+ seconds with
|
||||
# `docker logs` showing nothing at all, including the startup line, while the
|
||||
# process was confirmed alive and running; docker stop's SIGTERM (Godot has
|
||||
# no SIGTERM hook, see SERVER.md) then killed it without ever flushing that
|
||||
# buffered output, losing it permanently rather than merely delaying it.
|
||||
# `stdbuf -oL -eL` forces line buffering via LD_PRELOAD without touching the
|
||||
# binary; re-verified the same scenario then shows the startup line within
|
||||
# 3s. Fall back to running unwrapped if stdbuf isn't available (e.g. a
|
||||
# minimal image without GNU coreutils) rather than failing to start at all --
|
||||
# a server with delayed logs is still far better than no server.
|
||||
if command -v stdbuf >/dev/null 2>&1; then
|
||||
exec stdbuf -oL -eL "$(dirname "$0")/CosmicClashServer.x86_64" --headless -- "$@"
|
||||
fi
|
||||
exec "$(dirname "$0")/CosmicClashServer.x86_64" --headless -- "$@"
|
||||
|
||||
Reference in New Issue
Block a user