Skip to content

fleet-queue: port the pg_cron sweepers (expire standalone, parked revalidation, events prune) #6803

Closed

Description

@dezren39

Port the PG pg_cron queue sweepers to the Turso backend

Follow-up from the Turso queue cutover (#6741, runbook doc/fleet/queue-turso-cutover.md deviations 3–5). On Postgres, pg_cron ran three queue jobs inside muse-dev2; the Turso backend covers only the first, and only lazily:

  1. expire_leases — PORTED, but it runs inside claim_repo_task (as in the PG function body). PG also ran it standalone every minute (agent-expire-leases). Effect of the gap: expired leases sit until the next claim against any queue (expire is global, so any claim sweeps all queues — the practical gap is small but real when no claims happen).
  2. revalidate_parked_tasks (daily, park-revalidation-daily) — NOT ported: parked tasks whose ready conditions are non-time-based never auto-release in Turso mode. Time parks already release through claim at not_before.
  3. prune_events (daily, agent-prune-events, 30-day retention) — NOT ported: the Turso events table grows unbounded.

Work: add a broker-side periodic task (or a small systemd timer driving a fleet verb) that runs expire_leases on a cadence, revalidates parked tasks per the PG ready-condition semantics (recovered shapes are in the park implementation in turso_queue.rs), and prunes events older than 30 days. Keep the semantics identical to the PG bodies where they were recovered; note any deviation on this issue.

Acceptance: with the sweeper live, (a) a task claimed with a short lease returns to queued without any intervening claim, (b) a parked task with a satisfiable non-time ready condition releases, (c) events rows older than 30 days are deleted and newer rows untouched — each proven against the live fleet-queue DB with readback.

Acceptance criteria

  • A broker-side periodic mechanism runs lease expiry on a schedule (not only lazily inside claim), demonstrated by an expired lease being swept while no claims occur
  • Parked tasks with non-time ready conditions are revalidated on a schedule in Turso mode, or the gap is explicitly accepted and recorded with reasoning
  • The Turso events table is pruned to the 30-day retention the PG agent-prune-events job enforced, with the prune observable in logs/metrics

Activity

  1. developing-today commented on Nov 7, 2026

    @developing-today
    Contributor
  2. added
    kind/infrastructureInfrastructure / host-portability work
    priority/normalOrdinary priority (the default)
    effort/mMedium: expected under 1 day of work
    meta/enrichedIntake review done: acceptance criteria, links, and normalized labels added
    on Nov 7, 2026
  3. dezren39 commented on Nov 7, 2026

    @dezren39
    MemberAuthor

    Intake review

    Related: issue #6741 (Turso queue cutover; runbook deviations 3–5 per the issue body), issue #6838 (sibling missing-verb gap from the same cutover). Notes: item 1's practical gap is small (any claim sweeps all queues) — items 2 and 3 are the load-bearing ones; the events table grows unbounded until item 3 lands. Suggested approach: one systemd timer driving a fleet verb, mirroring the PG pg_cron cadences (1m expire, daily revalidate, daily prune).

    — Fleet monitor intake (repo-fleet-monitor, 2026-11-07 run): acceptance criteria appended to the issue body, labels normalized (kind/infrastructure, priority/normal, effort/m, status/needs-triage, meta/enriched), marked meta/enriched. No merged PR or commit was found this run that explicitly resolves this issue, so it stays open.

  4. added
    queue/queuedHas a queued task in the Supabase agent queue
    task/triageQueue packet kind: verify, reproduce, and route this item
    on Nov 7, 2026
  5. dezren39 commented on Nov 7, 2026

    @dezren39
    MemberAuthor

    F4 linkage from the #5690 flip checklist (Lane B, 2026-11-07): the broker-side revalidator sweeper in this issue is checklist item F4 (and the events-prune port is F7). Verified today that only the /events-seen primitive exists in the broker code — there is no sweeper job or observe mode yet, so there was nothing to enable in observe-only mode during the fleet-fetch sink flip.

    Two things that raise this item's weight since filing:

    1. fleet-fetch's AGENT_EVENTS_SINK was flipped to turso today (2026-11-07T16:44:52Z, proof on design: move agent append streams (agent.events, agent.quota_records) from Supabase to Turso staging #5690) — snapshot_refresh rows now land only in the fleet-queue Turso stream, so event_seen revalidation against the PG stream can never see them.
    2. The PG pg_cron park-revalidation-daily cannot substitute: PG (muse-dev2) has been down since 2026-11-06 19:25Z (infra: repo-queue PostgREST timeout: global failures lane-visible again — recurrence after #6450 closed (2026-11-06 21:15-21:31Z) #6619), and on its return it would read a PG agent.events stream that is missing every turso-only row.

    Ask for the implementation: first land in observe-only mode (log would-releases) for one daily cycle, per procedure C3 in doc/fleet/agent-events-turso.md, before enabling releases.

  6. added a commit that references this issue on Nov 8, 2026
  7. dezren39 commented on Nov 8, 2026

    @dezren39
    MemberAuthor

    Shipped 2026-11-07 (overnight lane 3) — PR #6986 merged; sweepers live on the Turso fleet-queue.

    What runs now

    • Broker POST /sweep (expire / prune / revalidate) — broker binary rebuilt from the PR branch, queue-broker.service restarted.
    • fleet-queue-expire.timer — every minute (first timer-fired cycle observed 18:09:00 CST, expired_leases: 0 that minute).
    • fleet-queue-sweeper.timer — daily 05:17 CST + delay (next: Sun 2026-11-08 ~05:20). Canonical definitions in home/common/default.nix (this PR); the live units are hand-installed copies until the next home-manager switch.

    Proof counts (live fleet-queue, seeded fixtures, cleaned up)

    • expire: sweep call returned expired_leases: 1 for a 5s-lease fixture → queued, binding cleared, lease row deleted, no claim involved.
    • revalidate observe: checked 89 · would_release 2 (the two fixtures) · confirmed 81 · stale 6 — no real parked task would release. Enabled: released 2/2 fixtures with park_released events; time park confirmed, stayed parked.
    • prune (30d): seeded 31d row deleted, 29d row kept, events_pruned self-logged. Real deletions begin once cutover-era rows age past 30 days.

    One gated step remains (by design, procedure C3): the revalidator runs observe-only. The observe data says enabling is safe (0 real would-releases). After the first scheduled cycle (Sun 2026-11-08 ~05:20 CST) is eyeballed, enable releases with:
    echo enabled > ~/.config/queue-broker/revalidator-mode (laptop; takes effect on the next daily cycle, no restart).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    effort/mMedium: expected under 1 day of workkind/infrastructureInfrastructure / host-portability workmeta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedpriority/normalOrdinary priority (the default)queue/queuedHas a queued task in the Supabase agent queuestatus/needs-triageNot yet triaged; needs a first lookstatus:donetask/triageQueue packet kind: verify, reproduce, and route this item

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions