Flow runs wait their turn in a queue per project and base #196

Merged
agra merged 5 commits from task/3759-s1-the-queue-in-the-store-and-its-slots into master 2026-10-31 00:02:09 +02:00
Owner

Tracker: #3759

Step 1 of #3672's planspec (note revision 5): the queue in the store, and its slots.

What it delivers

  • Every dispatch joins the queue of its task's project and the base it merges into, as a queued flow run. A queue runs one flow run at a time until its slots are set; 0 slots holds it. A run its queue began holds a slot until it ends, done or stopped, and keeps it while it waits on Agra or is blocked at a Wait.
  • Whenever a queue has a free slot, advance_queues begins its first queued run, by position, whose task waits on nothing: no task it follows or that blocks it is undone (its status done, or its latest started flow run ended done). Every store write that answers the runs it queues calls it once before its COMMIT.
  • start_flow splits into enqueue_flow and begin_flow. A Wait's blockers and Run steps' steps begin at once outside the slots, and begin a queued run their task already has. A run held at a Wait takes the queued runs of its pending blockers out of their queues, a blocks relation created onto its task included, so a queue never waits on itself.
  • Run steps begins a step's queued run whenever the step has one, so a step dispatched again by hand after its run was stopped begins outside the slots and resumes the plan that holds its queue's slot.
  • Stop ends a queued run stopped, with no started_at, and renumbers the runs behind it; a task its earlier run made done stays done. Stopping a holder frees its slot.
  • A task's latest started run (its latest run, by id, with a started_at) decides done_by, steps_on, blockers_told and BlockingTask.latest.
  • Migration 56 rebuilds flow_run through apply_rebuild: the queued state, queue_pos, started_at, from_queue, options, images and proposal_option, with the task's CHECKs, and adds flow_queue. The backfill gives every run its created_at as started_at, and from_queue 1 to every run no queued event with part flow names, in one uncorrelated pass over the events.
  • PUT /api/projects/:id/queues takes {base, slots} and answers the queue; a base branch_valid refuses or negative slots answer 400 invalid. GET /api/flow-runs?state=queued lists queued runs. docs/api.md documents the queued state, the Queues section and the route.
  • The web maps the queued flow-run state to the design system's queued state, and the task's flow card offers Stop on a queued run.

Tests

  • tests/flow_queue.sx pins each acceptance case of the task, the version-55 upgrade included, and a step dispatched again by hand after its run was stopped beginning outside the slots while its plan holds the queue's slot.
    • Fail-before for that case: at 0acbc0c1 the re-dispatched step's run stays queued at position 1 and the plan stays needs_you; with the fix it begins and the plan resumes at its Run steps.
  • tests/blockers.sx, routing.sx, runner_core.sx, named_runner.sx and tags.sx set their project's slots through the route, as do flow_prompt.sx, runner_channel.sx, runner_lost.sx and runner_view.sx, which also dispatch several flows into one project. tests/blockers.sx makes held block tid once tid's run has begun.
  • The e2e fixtures set slots for the projects they dispatch into, and stopAll stops queued runs. No golden is added or changed.

Gates

  • sak-gate full, gate run 1 at e0ede19f: passed (72 sx tests, step9_release, the deploy contract, e2e 777 passed, runner e2e 10 passed).
Tracker: [#3759](https://sak.swipelab.com/tasks/3759) Step 1 of [#3672](https://sak.swipelab.com/tasks/3672)'s planspec (note revision 5): the queue in the store, and its slots. ## What it delivers - Every dispatch joins the queue of its task's project and the base it merges into, as a `queued` flow run. A queue runs one flow run at a time until its slots are set; 0 slots holds it. A run its queue began holds a slot until it ends, done or stopped, and keeps it while it waits on Agra or is blocked at a Wait. - Whenever a queue has a free slot, `advance_queues` begins its first queued run, by position, whose task waits on nothing: no task it follows or that blocks it is undone (its status done, or its latest started flow run ended done). Every store write that answers the runs it queues calls it once before its COMMIT. - `start_flow` splits into `enqueue_flow` and `begin_flow`. A Wait's blockers and Run steps' steps begin at once outside the slots, and begin a queued run their task already has. A run held at a Wait takes the queued runs of its pending blockers out of their queues, a `blocks` relation created onto its task included, so a queue never waits on itself. - Run steps begins a step's queued run whenever the step has one, so a step dispatched again by hand after its run was stopped begins outside the slots and resumes the plan that holds its queue's slot. - Stop ends a queued run stopped, with no `started_at`, and renumbers the runs behind it; a task its earlier run made done stays done. Stopping a holder frees its slot. - A task's latest started run (its latest run, by id, with a `started_at`) decides `done_by`, `steps_on`, `blockers_told` and `BlockingTask.latest`. - Migration 56 rebuilds `flow_run` through `apply_rebuild`: the `queued` state, `queue_pos`, `started_at`, `from_queue`, `options`, `images` and `proposal_option`, with the task's CHECKs, and adds `flow_queue`. The backfill gives every run its `created_at` as `started_at`, and `from_queue` 1 to every run no `queued` event with part `flow` names, in one uncorrelated pass over the events. - `PUT /api/projects/:id/queues` takes `{base, slots}` and answers the queue; a base `branch_valid` refuses or negative slots answer 400 `invalid`. `GET /api/flow-runs?state=queued` lists queued runs. docs/api.md documents the `queued` state, the Queues section and the route. - The web maps the `queued` flow-run state to the design system's queued state, and the task's flow card offers Stop on a queued run. ## Tests - tests/flow_queue.sx pins each acceptance case of the task, the version-55 upgrade included, and a step dispatched again by hand after its run was stopped beginning outside the slots while its plan holds the queue's slot. - Fail-before for that case: at 0acbc0c1 the re-dispatched step's run stays `queued` at position 1 and the plan stays `needs_you`; with the fix it begins and the plan resumes at its Run steps. - tests/blockers.sx, routing.sx, runner_core.sx, named_runner.sx and tags.sx set their project's slots through the route, as do flow_prompt.sx, runner_channel.sx, runner_lost.sx and runner_view.sx, which also dispatch several flows into one project. tests/blockers.sx makes `held` block `tid` once tid's run has begun. - The e2e fixtures set slots for the projects they dispatch into, and `stopAll` stops queued runs. No golden is added or changed. ## Gates - `sak-gate full`, gate run 1 at e0ede19f: passed (72 sx tests, step9_release, the deploy contract, e2e 777 passed, runner e2e 10 passed).
Every dispatch joins the queue of its task's project and the base it merges
into, queued, and a queue runs one flow run at a time until its slots are set
through PUT /api/projects/:id/queues. Whenever a queue has a free slot it
begins its first queued run whose task waits on nothing it follows or is
blocked by. A Wait's blockers and Run steps' steps begin outside the slots,
and a run held at a Wait takes its blockers' queued runs out of their queue.
Migration 56 rebuilds flow_run with the queued state, its place, when it
began and whether its queue began it, and adds flow_queue.
agra changed title from Flow runs wait their turn in a queue per project and base, and a queue begins its next run whenever it has a free slot to Flow runs wait their turn in a queue per project and base, which begins its next run whenever it has a free slot 2026-10-30 23:00:07 +02:00
agra changed title from Flow runs wait their turn in a queue per project and base, which begins its next run whenever it has a free slot to Flow runs wait their turn in a queue per project and base 2026-10-30 23:31:51 +02:00
A step dispatched again once its flow run was stopped joins its plan's
queue, whose slot the plan holds while it waits on Agra about that step.
Run steps now begins that queued run outside the slots and resumes the
plan, as it does a step's first run, so the queue never waits on itself.
agra merged commit 3f5a3072f6 into master 2026-10-31 00:02:09 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sx/sak!196
No description provided.