krz/hutch-stats

Server-side utility for calculating contributions for sourcehut users.

clone: git clone https://gitbay.org/krz/hutch-stats.git

main: alembic/versions/20260411_0006_actor_queue_scheduling.py · raw

 1"""tracked actor queue scheduling fields"""
 2
 3from __future__ import annotations
 4
 5from alembic import op
 6import sqlalchemy as sa
 7from sqlalchemy import inspect
 8
 9
10revision = "20260411_0006"
11down_revision = "20260411_0005"
12branch_labels = None
13depends_on = None
14
15
16def _column_names(table_name: str) -> set[str]:
17    return {column["name"] for column in inspect(op.get_bind()).get_columns(table_name)}
18
19
20def upgrade() -> None:
21    columns = _column_names("tracked_actors")
22
23    if "discovery_state" not in columns:
24        op.add_column(
25            "tracked_actors",
26            sa.Column("discovery_state", sa.String(length=32), nullable=False, server_default="queued"),
27        )
28    if "queued_for_discovery_at" not in columns:
29        op.add_column("tracked_actors", sa.Column("queued_for_discovery_at", sa.DateTime(timezone=True), nullable=True))
30    if "next_poll_after" not in columns:
31        op.add_column("tracked_actors", sa.Column("next_poll_after", sa.DateTime(timezone=True), nullable=True))
32    if "last_claimed_at" not in columns:
33        op.add_column("tracked_actors", sa.Column("last_claimed_at", sa.DateTime(timezone=True), nullable=True))
34    if "poll_attempts" not in columns:
35        op.add_column(
36            "tracked_actors",
37            sa.Column("poll_attempts", sa.Integer(), nullable=False, server_default="0"),
38        )
39
40    op.execute(
41        sa.text(
42            """
43            UPDATE tracked_actors
44            SET discovery_state = CASE
45                WHEN last_poll_status IS NOT NULL THEN last_poll_status
46                ELSE 'queued'
47            END
48            """
49        )
50    )
51    op.execute(
52        sa.text(
53            """
54            UPDATE tracked_actors
55            SET queued_for_discovery_at = COALESCE(queued_for_discovery_at, last_requested_at, last_polled_at, CURRENT_TIMESTAMP)
56            """
57        )
58    )
59    op.execute(
60        sa.text(
61            """
62            UPDATE tracked_actors
63            SET next_poll_after = COALESCE(next_poll_after, last_polled_at, CURRENT_TIMESTAMP)
64            """
65        )
66    )
67
68
69def downgrade() -> None:
70    columns = _column_names("tracked_actors")
71    if "poll_attempts" in columns:
72        op.drop_column("tracked_actors", "poll_attempts")
73    if "last_claimed_at" in columns:
74        op.drop_column("tracked_actors", "last_claimed_at")
75    if "next_poll_after" in columns:
76        op.drop_column("tracked_actors", "next_poll_after")
77    if "queued_for_discovery_at" in columns:
78        op.drop_column("tracked_actors", "queued_for_discovery_at")
79    if "discovery_state" in columns:
80        op.drop_column("tracked_actors", "discovery_state")