Raises bet throughput from ~166 to ~318 per second, measured. A 20-second betting window now absorbs roughly 6,400 bets instead of 3,300. A bet reserves synchronously in memory and writes in the background. The reservation counts against the balance immediately, so two concurrent spends of the same funds cannot both succeed while the first sits in the buffer — twelve goroutines racing for one balance yield exactly one winner. The first attempt was slower than no batching at all, because Flush still called Post per transaction and each kept its own commit. Amortising the scheduling is worthless; the fsync is the cost. PostMany now writes the whole batch in one database transaction, and a rejected group falls back to individual writes to isolate the offender. Safety rests on co-location: the reservation buffer and the round live in the same process, so a crash loses both together — the player was not charged and is not in the round. A round that flushed and then lost its process is already handled by the reconciler. Fixes a data race the detector found: MaxDelay was a public mutable field read by the flush loop, so any operator tuning it live would have raced. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
8.6 KiB
8.6 KiB