mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-13 16:12:05 +00:00
docs: design per-match server autoscaling, with measured boot time
Casual/ranked queues need servers allocated per match and shut down afterwards, so cost is incurred only while a match runs - while the existing Docker and CI gates keep passing unchanged. Measured against the repo's own cosmicclash-server image rather than estimated: the runtime image is ~148 MB of content, and boot to the server_started line is ~870 ms on the container's own clock. That was taken under x86_64 emulation on an arm64 host, so it is a pessimistic bound and is recorded as one - it needs re-measuring on native Linux before it sets any timeout. Two findings that would each break a naive implementation, both hit while taking that measurement: - Godot's stdout is block-buffered off a TTY. A detached container logs nothing at all - server_started does not appear even after 35s - so an orchestrator readiness probe that greps the log hangs forever. Probe the UDP socket or flush explicitly. - --port defaults to 7777 and the Dockerfile hardcodes EXPOSE 7777/udp, so several matches cannot share a host without a port range or an address per match. Being UDP, L7 ingress routing does not apply. Also records the honest tension in 'only pay during a match': a server must listen before players connect, and image pull plus scheduling can dwarf 870 ms, so the recommendation is match-level scale-to-zero over a small warm node pool rather than node-level scale-to-zero. The rule for keeping verify-phase6 and verify-enet-integration green: every allocation feature is opt-in via a ServerConfig flag defaulting to current behaviour, with a second Compose file rather than mutating compose.phase6-smoke.yml.
This commit is contained in:
@@ -51,6 +51,28 @@ spoofable identity is worse than no rating.
|
||||
- [ ] Casual and ranked playlist rulesets (backfill, bots, abandon penalties,
|
||||
arena restriction — see the comparison table in the design doc).
|
||||
|
||||
Server orchestration (same phase — the servers must autoscale and bill only
|
||||
for the duration of a match):
|
||||
|
||||
- [ ] Choose the orchestrator (Agones on Kubernetes is the recommended
|
||||
default; it models allocation, readiness and per-match lifetime natively).
|
||||
- [ ] Fix readiness detection. Godot's stdout is block-buffered off a TTY, so
|
||||
`server_started` never appears in `docker logs` for a detached container —
|
||||
a log-grep readiness probe hangs forever. Probe the UDP socket, or flush.
|
||||
- [ ] Support more than one match per host: a per-container port from a range,
|
||||
or one address per match. `--port` defaults to 7777 and the Dockerfile
|
||||
hardcodes `EXPOSE 7777/udp`.
|
||||
- [ ] Add a no-show timeout so an allocated server that never fills abandons
|
||||
and exits instead of idling at cost.
|
||||
- [ ] Re-measure boot-to-listening on native x86_64 Linux. The repo's current
|
||||
figure is ~870 ms, measured under emulation on arm64 — a pessimistic bound.
|
||||
- [ ] Re-measure the SERVER.md sizing estimate (6–10 processes/core,
|
||||
150–250 MB RSS) under real concurrency before it sizes a bill.
|
||||
- [ ] Keep `make verify-phase6` and `make verify-enet-integration` green:
|
||||
every allocation feature is opt-in via a `ServerConfig` flag defaulting to
|
||||
today's behaviour, with a second Compose file for the allocated path rather
|
||||
than mutating `compose.phase6-smoke.yml`.
|
||||
|
||||
## Known issues to resolve before public hosting
|
||||
|
||||
- [ ] Slot reclaim is currently keyed by display name, so someone can take a
|
||||
|
||||
Reference in New Issue
Block a user