Snapshot a round's timing when it opens (B-61)
round_duration_seconds was read live on every scheduler tick and every bet check, with the deadline computed as opened_at + duration. Lowering it from 600 to 60 while a round was 300s in closed that round instantly; raising it moved the closes_at clients were already counting down to. round_cooldown_seconds had the same property for the gap after a close. B-11 fixed this class of problem for the advertised jackpot; the timing fields were left live. Round now carries duration_seconds and cooldown_seconds, set from the config when it opens. round_deadline() is the single place the deadline is computed — the scheduler, place_bet's two checks and /rounds/current's closes_at all go through it — and the cooldown is read off the round that just closed, so the gap a round announced is the gap that's honoured. The config row becomes what the *next* round opens with. The migration backfills from the live config rather than leaving the column defaults: an instance running 300s rounds would otherwise see the round currently in progress jump to 600s the moment this lands, which is precisely the retroactive change being fixed. Verified against a scratch DB with a non-default config. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
"""snapshot round timing onto the round row (B-61)
|
||||
|
||||
Revision ID: 283844a44b4a
|
||||
Revises: c1d4a97b5e10
|
||||
Create Date: 2026-08-03 23:05:04.996492
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '283844a44b4a'
|
||||
down_revision: Union[str, Sequence[str], None] = 'c1d4a97b5e10'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
"""Upgrade schema."""
|
||||
op.add_column('rounds', sa.Column('duration_seconds', sa.Integer(), server_default='600', nullable=False))
|
||||
op.add_column('rounds', sa.Column('cooldown_seconds', sa.Integer(), server_default='30', nullable=False))
|
||||
|
||||
# Backfill from the live config rather than leaving the column defaults: an
|
||||
# instance running with, say, a 300s round would otherwise see every existing
|
||||
# row — including the round currently in progress — jump to 600s the moment
|
||||
# this migration lands, which is exactly the retroactive change B-61 is about.
|
||||
op.execute(
|
||||
"UPDATE rounds SET "
|
||||
"duration_seconds = coalesce((SELECT round_duration_seconds FROM round_config LIMIT 1), 600), "
|
||||
"cooldown_seconds = coalesce((SELECT round_cooldown_seconds FROM round_config LIMIT 1), 30)"
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
"""Downgrade schema."""
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('rounds', 'cooldown_seconds')
|
||||
op.drop_column('rounds', 'duration_seconds')
|
||||
# ### end Alembic commands ###
|
||||
Reference in New Issue
Block a user