The settle was four autocommit statements — save, award, record, clear — sequenced so a crash between any two of them cost the player as little as possible. That reasoning holds for a game owned by one player, and the old comment made it well. It does not survive a pot, which is what the tables are about to become: pay the winner, die before the state write, and the hand still reads as live, so it settles again and pays again. Chips minted from nothing, and gogobee turns those into euros. The obvious fix is a trap. Award is a bare Get().Exec, so wrapping the settle in a transaction makes it wait for the connection the transaction is holding. Not an error — a hung process, and since the news app shares the pool it goes too. So storage.CommitHand does the lot in one Begin/Commit, with tx-taking award and recordHand beside the public ones. addChips has done it this way since the escrow ledger was written; this is only that pattern, applied where the money is. Two things fell out. A deal landing on a taken seat used to be refused and *then* refunded in a separate statement, so a crash in between took a stake for a game that existed nowhere — no felt, no audit row, nothing to find. And the audit row is now inside the settle, which means failing to write it rolls the payout back rather than paying quietly and logging: the payout and the audit row are the same fact, and a payout nobody can account for is worse than one that didn't happen. TestTheSettleDoesNotDeadlockAgainstItsOwnConnection is a canary, and it has been made to sing — put the bug back and it doesn't fail with a message, it hangs, and the timeout is the message. Which is exactly what production would do. A canary that has never sung is just a bird. Nothing a player can see has changed: eight blackjack hands conserving to the chip across win, lose and push (a natural is the sharp one — Fresh and Done in a single CommitHand), a double-deal 409 that refunds and leaves the live game alone, hangman, and a hold'em session that bought in for 200 and got up with 197. Also: the plan's deploy note was stale for the second time, with the lesson from the first time written directly underneath it. Everything is live and always was. A hand-written record of what is deployed will rot. Ask the box. Claude-Session: https://claude.ai/code/session_013M5nD7PgUboJXoDcYHzpuJ
6.7 KiB
6.7 KiB