Files
Adrian Lyjak 386f19043f Enforce workflow concurrency through DBOS worker queues (#732)
`DBOSRuntime` starts every control loop directly, so
`Workflow(num_concurrent_runs=...)` only limits runs under the basic
runtime. DBOS workers cannot apply the limit.

Now `register()` declares one DBOS queue per workflow, named
`_llamaindex_workflow_queue:<workflow_name>`, with `worker_concurrency`
set from `num_concurrent_runs`. Workflows with a limit submit through
the queue, and runs beyond the limit wait as `ENQUEUED`, admitting
within about `polling_interval_sec`. Workflows without a limit keep
starting directly, so the default path has no added latency. The
constructor rejects zero, negative, boolean, and non-integer limits.

The queue is declared even for unlimited workflows, so removing a limit
still leaves a listener for rows that were `ENQUEUED` under the old one.
Declarations live in a process-level map because DBOS's registry
survives `DBOS.destroy()` and rejects redeclaring a name. Recreating the
runtime reuses the queue object and updates its limit in place, which
DBOS's poller reads live.

The limit is per worker, so deployment capacity is the limit times the
number of live workers. Applications that restrict `DBOS.listen_queues`
collect `runtime.workflow_queues` after registering workflows and before
launch.
2026-08-13 21:19:25 -04:00
..