Integrations and authoring¶
ECA¶
The orchestra_eca submodule wires Orchestra to
ECA in both directions, so processes and
events trigger each other without code.
- ECA → Orchestra. A
StartProcessECA action launches a process instance from any ECA event. Model "when a node is published, start the review workflow" entirely in ECA. - Orchestra → ECA. An
eca_eventtask type emits a custom ECA event when a token reaches it. Drop the node into a workflow to fan out into anything ECA can do (send mail, set a field, call a service) and, if the node parks, resume the token once that work signals back.
flowchart LR
event([ECA event]) -->|StartProcess action| inst[Process instance]
inst --> node[eca_event task] -->|emits ECA event| eca([ECA reacts])
Visual authoring (Modeler)¶
The orchestra_modeler submodule lets you draw workflows in BPMN.io through
the Modeler API. A model owner
maps Orchestra's nodes and flows to BPMN components and back:
- Round-trips id-stable. A node's id is preserved across edits, so saving an unchanged diagram does not renumber nodes; running instances are never orphaned.
- Element templates carry each node's task type and its per-node settings (outcomes, payload variable, assignment fields, join/split) in the property panel; flow conditions ride on the links.
- A running-instance guard. A subscriber warns before you edit a workflow that still has running instances, since a structural change can strand them.
The optional orchestra_bpmn_io submodule adapts the BPMN.io editor to
Orchestra: it preserves a workflow's diagram layout when the same workflow is
saved from another modeler (Orchestra stores the node positions itself), and it
trims the editor's context pad to the shapes Orchestra can model, so the pad
never offers a native end event, intermediate event or shape-morph that the
workflow would silently drop on save.
Complete modeler (form-based)¶
The orchestra_cm submodule is a form-based alternative to the BPMN.io canvas:
it edits the same workflow as a list of node and flow sections, mapped to the
Modeler API by the same kind of model owner. It is the place to author the
node-level structures a diagram cannot show (escalation timers, assignments).
Each node, each flow, each node-feature editor, and the add-node / add-flow controls are collapsible sections collapsed by default, so a large workflow stays scannable: open only the ones you are working on. Every edit re-renders the structure in place (an AJAX Apply); the sections you have open stay open across that rebuild (a just-added or just-renamed item, and any section with a validation error, open automatically).
Apply (and every add, remove or clone) only changes the form's working copy: nothing is written until Save. Once anything has changed, a warning says so at the top of the form and below Save, and leaving the page asks first (the browser's own confirmation). Saving does not ask.
A brand-new workflow opens with its start node already there, in both editors: a workflow has exactly one start, so placing it is boilerplate. From then on the add-node control no longer offers the start type, and the canvas's own save refuses a second one.
In-editor Clone node and Clone flow buttons duplicate a single node, or a conditioned flow, within the workflow you are editing, a quick way to repeat a node-feature setup without retyping it. This is distinct from cloning a whole workflow (see Cloning, import and export).
Group¶
The optional orchestra_group submodule adds a Groups staffing audience,
so a human task is offered to the members of one or more
Group entities. It is a plugin and
nothing else: the node names group IDs, the audience mints a group:12
candidate token for each, and a viewer carries the same token for every group
they hold a membership of, so who may act is read from the membership as it
stands rather than from a list frozen when the task was created. Joining a
group therefore puts its open tasks in your inbox with nothing to re-run.
Membership is the whole dimension, deliberately: a group role in the outsider or insider scope is derived from a global role and applies to every group of its type, including groups nobody ever joined, so it cannot be enumerated from an account the way a viewer's token has to be. For notification the audience resolves to the groups' active members, capped like a role pool.
A second audience, Groups by variable, reads the group IDs from a process
variable instead, so an earlier step decides which groups handle the task: the
team that owns the content under review, say, or the department of the person
who made the request. The variable holds one group ID or a list of them (a
value that is not a group ID is skipped), and everything after that is the
same as Groups: the same group:12 tokens, the same live membership, the
same capped notification. Nothing is checked when the workflow is saved, since
there is no group ID to check until the run gets there. A variable that is
missing, empty, or holds no group ID halts the step as soon as the run reaches
it; one naming a group that was deleted, or that nobody active is in, is caught
by the cron recovery sweep (see
a step nobody can take).
Cloning, import and export¶
Moving and duplicating workflows needs no Orchestra-specific tooling: it comes from the Modeler API (which Orchestra is a model owner of) and the config-entity ecosystem:
- Import / export: because Orchestra is a Modeler API model owner, the Modeler API adds a Models collection with an Import tab (import a model from a raw or archived file) and Export / Export as recipe operations on each model. So a workflow exports as a file or a shareable recipe and imports elsewhere, all from the UI.
- Clone: the Entity Clone module adds a Clone operation that duplicates a workflow under a new machine name, a quick way to base a new workflow on an existing one.
- A workflow is also a plain config entity, so
drush config:export/config:importround-trips it as YAML for developer config workflows.
So a workflow authored on one site can be cloned, exported and re-imported elsewhere through tools already in place.
Examples¶
The orchestra_examples submodule ships ready-to-run workflows, each
demonstrating one capability. Enable the module, then start any of them from the
UI or WorkflowEngine::start(). It also ships the
Orchestra reviewer role (orchestra_reviewer, carrying Process Orchestra
tasks), which is the role pool the quorum ballots and the escalation ladder
are assigned to: grant it to an account to answer their tasks.
| Workflow | Shows |
|---|---|
example_linear |
A linear flow that parks on a wait and resumes when signaled. |
example_exclusive |
An exclusive choice (approve / reject) driven by flow conditions. |
example_parallel |
A parallel split and a wait_all join waiting for both branches. |
example_inclusive |
An inclusive split and a matching join over the live branches. |
example_quorum |
A synchronous quorum (wait_all + merge + count) whose ballots also demonstrate the structured task-assignment form, including a union of two assignments. |
example_member_validation |
A per_member split asking every member of the reviewer role and the board chair to validate, each in a task of their own, decided by a quorum join by majority. |
example_review |
A comment task: the inbox opens a comment form with one labeled button per outcome, and a note is required to reject. |
example_approval |
The same comment task with a note required for either decision, the comment and the scalar outcome landing in variables of their own. |
example_reminder |
A timeout whose notify action turns the deadline into a recurring reminder, leaving the step parked. |
example_escalation |
A staggered timers ladder on one task: remind, then fork an escalation branch to a manager while the task keeps waiting, then give up with an expired outcome. |
example_eca_sync |
An ECA round-trip: the step raises an event and an ECA model answers within the same advance. |
example_eca_cron |
The same round-trip answered later, on cron, so the token stays parked in between. |