Problem
Orchestra advances a process by enqueuing each active token to the orchestra_advance queue, which is drained by the queue worker on cron. A process started or signalled in a web request therefore advances exactly one node and then waits for the next cron run (or a manual drush queue:run orchestra_advance) to move further. On a site with no cron configured, a started process never advances at all, which looks broken.
For interactive or low-latency processes, and for a smooth first-run experience, there should be a way to advance a process to its next stable state (a parked human task, a wait, or completion) immediately, in the same request, without waiting for cron.
Proposed solution
Add an opt-in synchronous execution mode. When it is in effect for a process, after a top-level operation (start, signal, spawn) commits, the engine drains the orchestra_advance queue inline, processing each item in its own transaction exactly as cron does, until every token of the run has reached a stable state (parked, waiting, consumed or terminal).
Advancement cannot simply recurse inline: advance() runs each node in its own transaction and holds the join lock across it, releasing only after the commit, so advancing a successor inside that transaction would nest transactions and break the lock-after-commit guarantee. Draining the queue after the top-level operation commits keeps the existing per-node transaction and retry/dead-letter semantics intact.
Scope and configuration
- A site-wide setting
execution_modeonorchestra.settings, with valuesqueued(the default) andsynchronous. - A per-workflow override on the Workflow config entity: inherit the site default, force queued, or force synchronous.
- The effective mode for an operation is the workflow override, falling back to the site default.
Safety
- The inline drain is bounded by a maximum number of advances per request; beyond it the remaining tokens fall back to cron, with a logged warning, so a pathological no-wait loop cannot run away in a single request.
- A token whose advance fails is left for cron to retry or dead-letter through the existing machinery, rather than being retried in a tight inline loop.
- Queued stays the default, so existing installs are unaffected and synchronous is a deliberate opt-in.
Open question
Whether synchronous should ever be the default site-wide. Keeping queued as the default is non-breaking and avoids request-latency and back-pressure surprises on heavy or high-volume workflows, but a fresh site with no cron then shows no progress until cron is set up. The recommendation is to keep queued as the default and warn (in hook_requirements and the docs) when cron has not run recently, rather than defaulting to synchronous.
Issue fork orchestra-3605274
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
mably commentedComment #5
mably commented