Phase B runtime: the turn clock, the session reaper the plan noticed nobody had ever wired, and the game-agnostic seam the engines will plug into. - tableGame interface + a games() registry keyed on storage name, so the clock, the reaper and (soon) the handlers never know whether they drive poker or UNO. - The turn clock is the first goroutine in Pete to mutate game state. It obeys rule 1 (DueTables returns a plain slice — the rows are closed before any lock, or the scan would hold the one connection a locked write needs) and the version guard (act only if the table is still the version the scan saw). Tested against the exact double-move the plan warned of: a real move lands in the same tick the scan fired, bumps the version, and the clock steps aside instead of folding the next player who still had 25 seconds. - PushDeadlines on boot shoves every live clock out by a grace period, so the first tick after a deploy doesn't auto-fold the whole room at once. - ReapIdleSessions finally has a caller. A seated player is invisible to it — their chips are inside a table blob — so it only ever reaps loose idle chips. - publishTable fans a minimal version-carrying nudge through the hub; the frame is seat-blind, so a hole card never rides a broadcast that reaches the table. Clock wired into main.go behind gamesReady(). Still no engine implements tableGame, so the registry is empty and nothing a player can see has changed. Claude-Session: https://claude.ai/code/session_013M5nD7PgUboJXoDcYHzpuJ
3.6 KiB
3.6 KiB