Skip to content

How Workflows Run ​

Last updated

This section is the precise description of what the engine does. Read it before building anything that runs often or talks to equipment.

Order of execution ​

  1. A run starts. The server reads the saved workflow from the database and records a run with status running.
  2. Parameters passed with the run become variables.
  3. The engine finds the trigger node that actually fired and follows the wires from it. Run Now, the Schedules page and a Run Workflow node don't point at a single trigger, so those run from every trigger node in the workflow instead, one at a time.
  4. At each node it runs the node, stores its outputs — available to later nodes both as a wired data dot and as {{variables}} — and follows only the flow output the node chose (for example True or False). It then runs whatever is wired to that output.
  5. If one output has several wires, the targets run one after another, each to the end of its own chain, before the next starts. The order is the order the wires were drawn.
  6. When nothing is left to follow, the run is recorded as completed.

Everything is sequential except a Fork. A Delay of 10 s holds up everything after it on the same chain.

Parallel branches: Fork and Join ​

A Fork starts all of its wired branches at the same time: a Delay, On-Delay or slow Call URL on one branch does not hold up the others. Gather the branches again with a Join:

Join Continue whenWhat happens
All branches have arrived (default)Each branch that reaches the Join stops there, until the last one arrives; that one carries on past the Join. The Join counts its incoming wires, so wire every branch into it
The first branch arrivesThe first branch to arrive carries on; later arrivals stop at the Join (logged as another branch already continued)
  • If a branch fails, the run fails, and the other branches stop at their next node instead of carrying on.
  • A branch that never reaches an "all" Join — it took the other side of a Condition, say — leaves the Join waiting: the run still completes, and History records Join (all) never continued: 1 of 2 branches arrived.
  • Branches share the run's variables. Two branches setting the same variable at once: the last write wins.
  • A Join inside a Loop body fires once per pass, as long as every branch reaches it each time.

Note: A real event only runs the branch behind the trigger node that fired — a workflow with a Tag Change trigger and a Schedule trigger runs just the tag-change chain when the tag changes. Run Now, the Schedules page and a Run Workflow node have no single trigger to point at, so those still run every trigger branch in the workflow.

Overlapping runs ​

A workflow runs one at a time. If it is started again while a run is still in progress — a trigger firing again, a schedule, a button, a script — the new run is not started and is not queued for later: by the time the first run ends, the event that asked for it has passed. It is refused with Workflow "…" is already running, which is written to the server log, and a caller that waits for the result (a script, a Run Workflow node, a schedule) gets that error.

This keeps two runs from writing the same tags, sending the same emails and changing the same retentive counters at once. It also means events can be skipped while a slow run is going. If every event matters, keep the workflow short, or move the slow part (a long Delay, a slow Call URL) into a workflow it calls without waiting.

Typical ways to get many events at once:

  • Tag Value fires on every change of the tag while the condition is true, not once when it becomes true. A temperature bouncing around 86–88 °C with Threshold > 85 starts a run every time the value updates.
  • Tag Change on a noisy analog tag.
  • A Schedule interval shorter than the run takes (a 5 s interval on a workflow with a 10 s Delay).

To fire once per event, trigger on a boolean that the PLC or a ladder rung sets once (a one-shot), or use Tag Change on a status tag and check the new value with a Condition.

Errors ​

  • Any node that throws stops the whole run. Nodes already done stay done — there is no rollback.
  • The run is marked failed with the error message, which appears in History and in the list's Failed Last Run count.
  • A pop-up notification titled Workflow Failed, with the workflow name and the error, goes to every open browser, and the error is written to the server log.
  • Run Script, Run Workflow and Call URL have an Error output. When the called script or workflow fails, or the web server answers with an error status, the run continues from Error instead of failing. A network error (host unreachable, 10 s timeout) in Call URL still fails the run.
  • Send Message has an Error output too. Any failure continues from Error when something is wired to it, and fails the run when nothing is.
  • A node type the engine does not know is skipped.
  • _STATUS/Workflow/<workflow name>/Failed on the Local Tags device goes true, with the message in …/LastError. It goes back to false after the next run that succeeds.

The pop-up only reaches someone looking at a screen. To be told another way — email, SMS, a voice call — add an alarm rule on _STATUS/Workflow/<workflow name>/Failed (device Local Tags, Equal to 1) and attach it to a pipeline. See System Status Tags.

Loops and limits ​

LimitValue
Nesting (workflow calls workflow or script calls workflow)5 levels. Deeper calls fail with Maximum workflow nesting depth reached (5)
A Run Workflow node calling its own workflowRefused: Cannot call self recursively
Messages that start each other (script or workflow, here or between paired appliances)5 in a chain. The sixth is not sent: Message "…" not sent: it would be message 6 in a chain of messages that start each other (limit 5)
Script timeout (for a Run Script step)30 s wall-clock, including any time the script spends in await

Warning: A wire loop — wiring a node's output back to an earlier node — is not a good way to repeat something. Each trip round the loop is one more step against the 1,000-step limit below, so the run fails on its own with Workflow execution limit reached once it has gone round enough times; it does not need disabling or a service restart, and the rest of the appliance stays responsive while it runs. With a long Delay in the loop that failure can still take a while to arrive (up to 1,000 × the delay), so it is not a quick way to notice the mistake either. Use the Loop node for repetition, and a Schedule for polling.

Enabling and disabling ​

  • Enabled registers the triggers; Disabled removes them. Both take effect at once.
  • A run already in progress is never interrupted; it finishes normally.
  • A disabled workflow does not run from a schedule, a script, an alarm pipeline, a Run Workflow node, or a dashboard button pressed by an operator. They get the error Workflow "…" is disabled.
  • Run Now — by an editor or administrator, in the editor or from a button — still runs a disabled workflow, so you can test it before switching it on.
  • Saving an enabled workflow removes and re-registers its triggers, so Schedule intervals restart from zero. Startup triggers do not fire again.

Restarts and power loss ​

ThingAfter the Scada.Ink service restarts
Enabled workflowsTriggers are registered again automatically
Startup triggersFire about 0.1 s after the service starts
Runs in progressLost. When the service starts again they are marked failed in History with Interrupted: the appliance restarted during this run
Schedule interval timersStart counting from zero
Variables, non-retentive countersGone — they only ever live for one run
Retentive Timer, Run Hours, and Count Up/Down with Retentive tickedKept (stored in the database)
Tag Value / Tag ChangeFire again when the first values arrive from the device, if they count as a change

Run history ​

Each run stores its trigger data, step log and error. The newest 500 runs of each workflow are kept and older ones are deleted as new runs finish, so a busy workflow's history covers a shorter span of time, not more disk. A Tag Change workflow on a busy tag still does several database writes per run — trigger on slower signals.

Performance on the appliance ​

Workflows run inside the main API process. Each run makes several database writes (the run record and its step log). A handful of runs a minute is nothing; tens of runs a second from a noisy tag will load a the appliance noticeably. Move fast logic into ladder logic.

See also ​

Scada.Ink Help Center