|
morph 0.1.0
Asynchronous bridge between GUI thread and business models
|
IExecutor that queues every posted task and runs them only when the test explicitly asks, one at a time. More...
#include <step_executor.hpp>
Public Member Functions | |
| void | post (std::function< void()> task) override |
Enqueues task; does not run it. | |
| bool | runOne () |
| Runs exactly one queued task, oldest first (FIFO). | |
| std::size_t | runAll (std::size_t maxSteps=10 '000) |
| Runs every task currently queued, including ones a running task itself posts (e.g. a strand re-arming for its next queued item). | |
| std::size_t | pending () const |
| Number of tasks currently queued, awaiting a runOne()/runAll(). | |
| Public Member Functions inherited from morph::exec::IExecutor | |
| IExecutor (const IExecutor &)=delete | |
| IExecutor & | operator= (const IExecutor &)=delete |
| IExecutor (IExecutor &&)=delete | |
| IExecutor & | operator= (IExecutor &&)=delete |
| virtual bool | isSerial () const noexcept |
| Whether this executor runs one task at a time, each after the tasks posted before it: a strand, a GUI loop, a pumped MainThreadExecutor. | |
| ::core::async::IExecutor & | coreExecutor () noexcept |
| This executor as a core-cpp executor: the identity an core::async::ExecutorScope names. | |
IExecutor that queues every posted task and runs them only when the test explicitly asks, one at a time.
The public interleaving-test harness: any server component built on morph::exec::IExecutor — RemoteServer included — can be driven with fully deterministic, hand-stepped task ordering by constructing it against a StepExecutor instead of a ThreadPoolExecutor. RemoteServer posts every dispatch (both the top-level handle() post and the per-model strand dispatch its internal ModelStrands performs) onto whichever IExecutor it was constructed with, so controlling that one executor is enough to control ordering end-to-end — no need to name morph::exec::detail::ModelStrands or morph::exec::detail::ModelId to get there. A test picks which of several pending tasks (e.g. two different models' queued work) to run next via runOne(), observing RemoteServer's real per-model serialisation (a strand never posts its next task until the previous one has run) while still controlling the order two different models' work interleaves in.
Not thread-safe against concurrent runOne()/runAll() calls — intended for single-threaded, single-stepping test code, mirroring MainThreadExecutor's "owning thread" contract but without its wall-clock runFor() drain.
Definition at line 39 of file step_executor.hpp.
|
inlineoverridevirtual |
Enqueues task; does not run it.
Implements morph::exec::IExecutor.
Definition at line 43 of file step_executor.hpp.
|
inline |
Runs exactly one queued task, oldest first (FIFO).
Definition at line 50 of file step_executor.hpp.
|
inline |
Runs every task currently queued, including ones a running task itself posts (e.g. a strand re-arming for its next queued item).
Bounded at maxSteps rather than looping until the queue is empty: a task that keeps re-posting more work to this executor (a bug in the code under test, or a harness misuse) would otherwise turn this into an undetectable infinite loop, hanging the test process with no assertion failure and no compile-time signal. Real drains in this suite finish within a handful of steps, so the default is generous headroom, not a tight bound callers need to reason about.
| maxSteps | Upper bound on tasks run before giving up. |
Definition at line 79 of file step_executor.hpp.
|
inlinenodiscard |
Number of tasks currently queued, awaiting a runOne()/runAll().
Definition at line 94 of file step_executor.hpp.