Dead RCON is not fatal even when the adapter spawned the server, so a failed launch looks healthy #2

Open
opened 2026-07-26 14:02:03 +00:00 by aiko · 0 comments
Owner

This was generated by AI during triage.

Split out of #1, which parked pending a retest. This is the part of that issue's diagnosis that a code read confirmed, so it can proceed independently of the retest.

Agent Brief

Category: bug
Summary: A dead RCON connection is not fatal even when the adapter spawned the server itself, so a launch that failed produces a healthy-looking adapter.

Current behavior:
The adapter connects to RCON eagerly at startup. The comment on that code says this exists so a wrong password "fails loudly at startup instead of on the first redeem" — but the failure path does not do that. After the retry deadline expires (about 8 seconds) it prints one line to stderr and breaks out of the loop, then carries on: it connects to MPP, sends hello, receives its ack, and registers as a healthy adapter. Completely dead RCON is a stderr line nobody reads.

Separately, the spawned game process is fire-and-forget. Its handle is retained only so it can be terminated at exit, and its exit status is never inspected, so a binary that dies immediately after spawn goes unnoticed.

Together these mean a launch that achieved nothing still presents as a working session.

Desired behavior:

  • When the adapter spawned the server, a failed eager RCON connect is fatal: exit non-zero with a message naming the launcher path that was used, rather than registering with MPP. The operator should be pointed at the path they configured.
  • The spawned process is checked for having already exited (a poll()-style liveness check) before the session is treated as healthy; a binary that died immediately is reported as such, again naming the path.
  • When the adapter did not spawn a server — no launcher path configured, the deliberate manual/dev path where an operator starts Zandronum themselves — current behavior is preserved. Failing to reach RCON must not become fatal there, because assuming an already-running server is the documented intent of that mode. The distinction is "did I start this?", not "is RCON up?".

Key interfaces:

  • The startup sequence in the adapter's main(): the eager-connect result must gate MPP registration when a spawn occurred, instead of being advisory in all cases.
  • The retained spawned-process handle: currently used only for termination, needs an exit-status check.
  • The existing distinction between "a launcher path is configured" and "no path configured" already exists in the adapter and is the correct signal for whether a spawn happened. Reuse it rather than introducing a new flag.
  • Error text should name the configured path, since the whole failure mode is an operator pointing it at the wrong binary.

Acceptance criteria:

  • With a launcher path configured that cannot host the game, the adapter exits non-zero and the message names the path it launched.
  • A spawned process that exits immediately is detected and reported, rather than the adapter proceeding to register.
  • With no launcher path configured and no server running, behavior is unchanged from today (non-fatal, retries per invocation) — the manual/dev path still works.
  • With a launcher path configured and the server coming up correctly, startup succeeds as before.
  • The misleading comment claiming the eager connect already fails loudly is corrected or made true.

Out of scope:

  • Detecting whether the RCON server the adapter reached is the one it started. The ephemeral per-launch password already provides that property incidentally (see #1) and the leftover-server scenario is still unconfirmed pending retest.
  • The DOOM_RCON_PASSWORD behavior, which disables that incidental check.
  • Launcher-path validation in the Dashboard, which is mobrule#176 and explicitly does not catch a real-but-wrong executable.

Landing this change

This repo's git history is the tutorial. The RCON client and Launcher hosting are introduced in stage 2, which is the code at fault here, so the fix belongs in that stage rather than as a commit on top. That means the tutorial prose and the README both need updating in the same change — the README currently documents the no-path case as "assume a server is already up", which stays true but now sits beside a fatal path.

Landing in stage 2 requires rewriting staged history and force-pushing, which invalidates every existing clone. Prepare the change and stop before pushing; the operator authorises the force-push.

> *This was generated by AI during triage.* Split out of #1, which parked pending a retest. This is the part of that issue's diagnosis that a code read **confirmed**, so it can proceed independently of the retest. ## Agent Brief **Category:** bug **Summary:** A dead RCON connection is not fatal even when the adapter spawned the server itself, so a launch that failed produces a healthy-looking adapter. **Current behavior:** The adapter connects to RCON eagerly at startup. The comment on that code says this exists so a wrong password "fails loudly at startup instead of on the first redeem" — but the failure path does not do that. After the retry deadline expires (about 8 seconds) it prints one line to stderr and breaks out of the loop, then carries on: it connects to MPP, sends `hello`, receives its ack, and registers as a healthy adapter. Completely dead RCON is a stderr line nobody reads. Separately, the spawned game process is fire-and-forget. Its handle is retained only so it can be terminated at exit, and its exit status is never inspected, so a binary that dies immediately after spawn goes unnoticed. Together these mean a launch that achieved nothing still presents as a working session. **Desired behavior:** - When the adapter **spawned** the server, a failed eager RCON connect is **fatal**: exit non-zero with a message naming the launcher path that was used, rather than registering with MPP. The operator should be pointed at the path they configured. - The spawned process is checked for having already exited (a `poll()`-style liveness check) before the session is treated as healthy; a binary that died immediately is reported as such, again naming the path. - When the adapter did **not** spawn a server — no launcher path configured, the deliberate manual/dev path where an operator starts Zandronum themselves — current behavior is preserved. Failing to reach RCON must not become fatal there, because assuming an already-running server is the documented intent of that mode. The distinction is "did I start this?", not "is RCON up?". **Key interfaces:** - The startup sequence in the adapter's `main()`: the eager-connect result must gate MPP registration when a spawn occurred, instead of being advisory in all cases. - The retained spawned-process handle: currently used only for termination, needs an exit-status check. - The existing distinction between "a launcher path is configured" and "no path configured" already exists in the adapter and is the correct signal for whether a spawn happened. Reuse it rather than introducing a new flag. - Error text should name the configured path, since the whole failure mode is an operator pointing it at the wrong binary. **Acceptance criteria:** - [ ] With a launcher path configured that cannot host the game, the adapter exits non-zero and the message names the path it launched. - [ ] A spawned process that exits immediately is detected and reported, rather than the adapter proceeding to register. - [ ] With no launcher path configured and no server running, behavior is unchanged from today (non-fatal, retries per invocation) — the manual/dev path still works. - [ ] With a launcher path configured and the server coming up correctly, startup succeeds as before. - [ ] The misleading comment claiming the eager connect already fails loudly is corrected or made true. **Out of scope:** - Detecting whether the RCON server the adapter reached is the one it started. The ephemeral per-launch password already provides that property incidentally (see #1) and the leftover-server scenario is still unconfirmed pending retest. - The `DOOM_RCON_PASSWORD` behavior, which disables that incidental check. - Launcher-path validation in the Dashboard, which is `mobrule#176` and explicitly does not catch a real-but-wrong executable. ## Landing this change This repo's git history is the tutorial. The RCON client and Launcher hosting are introduced in **stage 2**, which is the code at fault here, so the fix belongs in that stage rather than as a commit on top. That means the tutorial prose and the README both need updating in the same change — the README currently documents the no-path case as "assume a server is already up", which stays true but now sits beside a fatal path. Landing in stage 2 requires rewriting staged history and force-pushing, which invalidates every existing clone. **Prepare the change and stop before pushing**; the operator authorises the force-push.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
mobrule/mobrule-pack-doom#2
No description provided.