#6501 Prune connections map on game teardown#6548
Conversation
The in-memory `connections` map was inserted into on host/join/reconnect but a `game_code` entry was never removed, unlike the parallel `game_spectators` map, leaking one entry per finished game. Remove the entry in both reaper teardown loops (grace-expiry and lobby-expiry), mirroring `specs.remove` and preserving state -> connections -> spectators lock order. Closes phase-rs#6501
|
🚨 Contributor flagged. Click here for more info: Superagent Dashboard |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughBackground maintenance now removes ChangesConnection Map Cleanup
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
matthewevans
left a comment
There was a problem hiding this comment.
Verdict: blocked — the teardown cleanup has no discriminating regression test.
🔴 Blocker
crates/phase-server/src/main.rs:1106 and :1147 remove expired game codes from the connections map, but this PR adds no test that drives either expiry path and proves the entry is removed while another game’s connection remains. The author’s cited compile check cannot fail when either conns.remove(game_code) is reverted.
Suggested fix: add a focused server/lifecycle test that seeds two connection-map entries, exercises both relevant teardown routes, and asserts only the expired game’s entry is pruned.
✅ Clean
The cleanup follows the existing state → connections → spectators lock order and leaves the send-before-removal behavior intact.
Recommendation: add the discriminating teardown regression test, then return for approval.
Summary
Fixes #6501: the in-memory
connectionsmap (crates/phase-server/src/main.rs) was inserted into on every host / join / reconnect but agame_codeentry was never removed, unlike the parallelgame_spectatorsmap which is pruned at the same teardown points. This leaks oneconnectionsentry per finished game.Root cause
connections: HashMap<String /*game_code*/, HashMap<PlayerId, Sender>>grows without bound: every completed or expired game leaves a permanentgame_code -> {seat -> dead Sender}entry.MAX_GAMESbounds only concurrent live sessions, not this map, so a long-running server accumulates one dead entry per game played.Fix
Mirror the existing
game_spectatorscleanup —connections.remove(game_code)in both background-reaper teardown loops:let conns→let mut connsand remove after the GameOver fan-out),connectionsprune block).Lock order is preserved throughout (
state -> connections -> spectators). No behavior change beyond releasing the dead entry.Files changed
crates/phase-server/src/main.rs—+14 / -1.Verification
cargo fmt --all— clean.cargo check -p phase-server— clean (compiles, borrow-checks). The change sits inside async websocket teardown paths that are not unit-testable in isolation; correctness follows from mirroring the adjacent, already-establishedgame_spectatorscleanup and preserving lock order.Summary by CodeRabbit