mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 08:32:41 +00:00
games: gogobee learns to poll Pete for money it has to move
Pete holds the chips; we hold the euros and are the only one who can move them. This is the loop that turns an escrow row on games.parodia.dev into a real balance change here. It is a poll because Pete cannot call us and isn't going to be able to. Every step is keyed on the escrow guid, because every step can be interrupted in the worst possible place: die after DebitIdem and before the verdict is queued, and Pete re-offers the row, we claim it again, the debit replays as a no-op and reports the same answer. The player is charged once. That is the only property here that really matters, and there is a test that kills us three times to prove it. The verdict rides the queue that already carries adventure facts — it wants the same durability, backoff and parking, so the row now says where it's going rather than the queue growing a twin. Flush sends it at once instead of after a 15s sender tick, because there's a person at the other end watching a spinner. First GET gogobee has ever made to Pete.
This commit is contained in:
@@ -457,6 +457,11 @@ func runMigrations(d *sql.DB) error {
|
||||
// message arrives once; a poll loop whose ack is lost on the wire will
|
||||
// retry, and without this the player pays twice. See euro.DebitIdem.
|
||||
`ALTER TABLE euro_transactions ADD COLUMN external_id TEXT`,
|
||||
// Pete games — the outbound queue carries more than adventure facts now.
|
||||
// An escrow verdict goes to a different Pete endpoint, but it wants the
|
||||
// same durability, backoff and parking, so it rides the same queue and the
|
||||
// row says where it's going. Existing rows are all facts, hence the default.
|
||||
`ALTER TABLE pete_emit_queue ADD COLUMN path TEXT NOT NULL DEFAULT '/api/ingest/adventure'`,
|
||||
}
|
||||
for _, stmt := range columnMigrations {
|
||||
if _, err := d.Exec(stmt); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user