|
Motion Master 6.0.0-alpha.86
Next-generation motion control software
|
Runs off-RT command-and-wait procedures and remembers how each one went. More...
#include <procedure_manager.h>
Public Member Functions | |
| ProcedureManager (DeviceManager &deviceManager) | |
| Binds the manager to the device set its procedures will run against. | |
| ~ProcedureManager () | |
| Requests cancellation of every running procedure and waits for them to finish. | |
| ProcedureManager (const ProcedureManager &)=delete | |
| ProcedureManager & | operator= (const ProcedureManager &)=delete |
| std::expected< void, ProcedureError > | start (uint16_t devicePosition, std::string name, std::vector< ProgressStep > steps, ProcedureBody body) |
Starts name on devicePosition, returning as soon as the run is under way. | |
| std::optional< ProcedureSnapshot > | snapshot (uint16_t devicePosition, std::string_view name) const |
The current or last-known state of name on devicePosition. | |
| bool | cancel (uint16_t devicePosition, std::string_view name) |
Asks the running name on devicePosition to stop. | |
Runs off-RT command-and-wait procedures and remembers how each one went.
The MonitoringManager analogue for procedures: it owns the cancellable std::jthread each run executes on, the per-device exclusion that stops two runs colliding, and the snapshot a client polls. What it does not own is any knowledge of what a procedure does — bodies are supplied at start, so adding a procedure never touches this class.
Exclusion is per device, and it is the part a mutex cannot provide. The driver's control-plane lock serialises individual transactions (one SDO, one mailbox round-trip), but a procedure is a multi-second span of many transactions interleaved with sleeps. "This device is
busy detecting its offset" is a span-level fact, so start rejects a second run on a device that already has one, and the claim is released when the thread exits — success, failure or cancellation alike.
Progress is polled, never pushed. This class holds no publish callback and names no WebSocket. Each snapshot is an accumulating full-array state in which finished steps keep their terminal status and value, which is what makes polling lossless: a step that starts and finishes between two polls is still visible as succeeded. See ProcedureSnapshot.
A snapshot outlives its run — retained per (device, procedure) until the next run of the same procedure replaces it — so a client that reconnects, or a user returning to a page, sees how the last run went rather than an empty state.
Retained snapshots are dropped when the device set is rebuilt. Positions may remap across a scan / reset, and a retained measurement rendered against a different physical drive is worse than no measurement at all. The rebuild is noticed by watching DeviceManager::topologyGeneration rather than by being told, which is what keeps DeviceManager unaware that procedures exist. A rescan can overlap any run, because a run holds no lock — so the sweep leaves a still-running entry alone and collects it later. See discardIfRescanned, where that is a correctness requirement rather than a nicety.
Thread-safe; start, snapshot and cancel may be called from any non-RT thread.
|
inlineexplicit |
Binds the manager to the device set its procedures will run against.
| deviceManager | Must outlive this manager. |
| mm::node::ProcedureManager::~ProcedureManager | ( | ) |
Requests cancellation of every running procedure and waits for them to finish.
|
delete |
| bool mm::node::ProcedureManager::cancel | ( | uint16_t | devicePosition, |
| std::string_view | name | ||
| ) |
Asks the running name on devicePosition to stop.
Cooperative: it requests the run's stop token and returns immediately. The body decides how promptly it notices — typically at its next step boundary or poll — after which the run finishes as kCancelled.
|
delete |
| std::optional< ProcedureSnapshot > mm::node::ProcedureManager::snapshot | ( | uint16_t | devicePosition, |
| std::string_view | name | ||
| ) | const |
The current or last-known state of name on devicePosition.
std::nullopt if that procedure never ran on that device since the last rebuild of the device set. (A caller that knows the procedure's step template can render an all-idle snapshot itself; the manager does not invent one, because it is only told a template when a run starts.) | std::expected< void, ProcedureError > mm::node::ProcedureManager::start | ( | uint16_t | devicePosition, |
| std::string | name, | ||
| std::vector< ProgressStep > | steps, | ||
| ProcedureBody | body | ||
| ) |
Starts name on devicePosition, returning as soon as the run is under way.
The device is checked to exist before anything is spawned, so an unknown position fails here rather than surfacing later as a failed snapshot. On success the run is immediately visible via snapshot with status kRunning and a bumped runCount.
| devicePosition | 1-based bus position the procedure runs against. |
| name | Procedure identifier, e.g. "os-command"; scopes the retained snapshot. |
| steps | The procedure's step template, in order, all idle. |
| body | The work to run (see ProcedureBody). |
ProcedureError).