Covers Engine 2.0.0
Execution and Timing
Understand inline calculations, scheduled tasks, and asynchronous delivery.
DARTWIC has several execution paths. Choose the path that matches when your logic must run, then measure the complete acquisition-to-output response in your deployment. Deterministic Automation defines the scheduler, health, and composition promises behind these paths, including the rule that external delivery must not become hidden callback work.
For most automation, dynamic channels and Lua are the right starting point. Fixed channels plus Native C++ DCode are the specialized prepared path for known repeated numeric work when measurement shows that a tighter, more predictable core cost is needed—commonly around a demanding 100–1,000 Hz loop, but never guaranteed by frequency alone. A standard Linux installation is not automatically real-time; hard physical deadlines require a real-time-capable, qualified host and measurement of the complete driver/device path. See choosing the path.
What runs when
| Work | Trigger | Timing boundary |
|---|---|---|
| Calculation attached to a channel being written | A write to that target | Runs inline before the target value is committed. |
| Calculation depending on another channel | An accepted dependency value commit | Runs inline after that commit, before the originating write returns. |
Populated DCode event trigger: | Activation, then dependency commits | Evaluated synchronously; no periodic condition polling. |
Event on_firing: | A change in the generated firing channel | Runs in the firing-channel calculation path. |
| Periodic task or state machine | Scheduled release | Runs on a CAESAR loop at its requested frequency. |
| Driver acquisition or command delivery | Driver-defined polling, callbacks, or workers | Depends on that module and its protocol. |
| Interface channel updates | Telemetry publication and subscription interval | Asynchronous; UI timing does not control engine execution. |
| History recording | Accepted writes and recording policy | Queued and flushed asynchronously. |
| Share delivery | Share publications, transport, and receive handling | Asynchronous across the link. |
A synchronous limit response
A pressure sample committed locally can immediately evaluate a DCode event condition. When the condition becomes numeric 1, DCode updates its firing channel before constructing and recording the event payload, so on_firing: can run on that local path. The operator board updates later.
Events shows the declaration. Use on_firing: for condition-driven logic. on_event: follows event-board lifecycle instead: acknowledgement, resolution, and silencing are operator state, not a sensor condition.
Synchronous describes call ordering, not a fixed time limit. An inline handler that sleeps, performs slow I/O, or calls a blocking native function delays its writer. Keep inline work bounded and avoid cycles; DCode detects calculation re-entry and reports an error.
Scheduled logic
CAESAR Tasks explains task creation, absolute release scheduling, task groups and failure diagnostics.
For fixed channels, CAESAR task transactions capture inputs and stage outputs until commit. Fixed and dynamic channels explains the consistency boundary and how it interacts with native DCode. DARTWIC Builder shows configuration work that waits for those transactions to finish.
At 10 Hz, a periodic task has a nominal 100 ms period. A value arriving just after an iteration may wait until a later iteration to be observed. Execution time, operating-system scheduling, holds, and missed releases can add delay. Increasing the target frequency does not establish a guaranteed deadline.
Use task diagnostics such as actual frequency, execution time, missed cycles, and timing status to detect overload. DCode’s missed: section can react to missed releases; it does not replay every missed sample. See Periodic Tasks.
The independently sampled task-health report adds active_overdue for a callback that remains active beyond its completion deadline and configuration_contention when a prepared fixed release is promptly rejected during fixed-channel reconfiguration. Both are actionable observations, not implicit hardware interlocks. See health and response.
Current failure behavior
Task groups order members that are due. A callback exception is logged and counted in _failed_cycles; the member still reports a dispatched cycle to the group, and later due members can run. Stopped members are skipped. Neither case automatically inhibits downstream automation or output. Missed-release diagnostics also do not establish a fault response for the hardware.
Inspect a group’s member_last_outcomes rather than assuming a preceding ordered member supplied a fresh successful result. The composition contract describes the available outcomes and the application decision they require.
Fixed snapshots preserve captured values, including old measurements. Undeclared reads in a partial snapshot can read live values, and stale handles return a numeric fallback. Declare every fixed input and explicitly validate measurement age and validity before using it for control. An unchanged numeric value alone cannot distinguish a steady measurement from failed acquisition.
Authority-denied value writes leave the live value unchanged and do not publish a successful commit notification. This applies to ordinary scalar/bulk writes, prepared inline reactions and fixed task batches. An accepted write still does not establish that hardware applied the command.
Command ownership, a local channel commit, and a successful physical action are separate facts. Choose fault responses from the hardware’s hazards and verify them with device feedback; a universal zero output is not a safe default for every device. The fixed-driver example is a simulation of the API workflow, not a safety-qualified controller.
From a software write to hardware
An accepted channel write means RAPID accepted and committed the value. It does not establish when a relay, valve, motor, or external controller changed state. That requires the driver to deliver the command and, where available, report feedback.
For an end-to-end measurement, account for:
- Device sampling and transport to the acquiring module.
- Local write, calculations, and event reactions.
- Command authority and driver dispatch or output polling.
- Network and device actuation time.
Keep the decision near the acquiring and actuating node when remote latency matters. A local calculation over a remote channel reacts to the arrival of the remote update, not the original physical measurement time.
Interpreting timing measurements
Native DCode and fixed records reduce work on the repeated execution path for a specific reason: the task can use storage, bindings, snapshots, and normal publication resources prepared before release instead of allocating or growing them in the cycle. The general core path still permits fallback allocation and has blocking locks. Compiling to C++ does not certify a callback or its inline dependencies. The native benchmark records host C++ allocation/free counts between observations and scheduled-release-to-completion time through missed-release recovery. These counts exclude Lua malloc and separately linked DLL allocators; zero host counts alone would not prove an allocation-free deployment.
A short desktop benchmark is evidence for that workload and run, not a worst-case deadline bound. Windows scheduling and competing machine load can delay a release even when its callback performs no allocation; missed releases alone do not identify whether the delay came from the OS, callback logic, or core contention. Include driver execution, recording, contention, and reconfiguration in qualification. A callback-duration number by itself omits scheduling lateness and can omit recovery work.
Reliability diagnostics
| Symptom | Inspect |
|---|---|
| Task falls behind | Actual frequency, execution time, missed cycles, held state. |
| UI skips intermediate values | Subscription interval and telemetry publication diagnostics. |
| History lags live data | Recording queue and persistence diagnostics. |
| Remote value stops changing | Share connection state, traffic, channel timestamp, stale timeout. |
| Output value does not change | Control policy, active controller, and command error. |
| Output value changes but hardware does not | Driver status and independent device feedback. |
Channels, Commanding and Control, and Telemetry and History explain the corresponding fields.