pub trait RunObserver {
// Required methods
fn on_task_started(&self, task: &TaskId);
fn on_stdout(&self, task: &TaskId, bytes: &[u8]);
fn on_stderr(&self, task: &TaskId, bytes: &[u8]);
fn on_task_finished(&self, task: &TaskId, record: &CompletedRecord);
fn on_task_skipped(&self, task: &TaskId, record: &SkipRecord);
fn on_task_cancelled(&self, task: &TaskId, record: &CancelledRecord);
}Expand description
Observation surface for one run_task invocation.
The four callbacks define a mode-agnostic surface: byte chunks
flow through RunObserver::on_stdout and
RunObserver::on_stderr for both fresh runs and cache hits.
Concrete implementations distinguish the EXEC-016 presentation
modes:
- A
bufferedobserver collects the chunks per task and emits one contiguous block to the parent process onRunObserver::on_task_finished. - A
liveobserver prefixes each line with[project:task]and writes it to a shared sink with per-line atomicity.
Implementations MAY use interior mutability; the trait methods
take &self so that one observer can serve many concurrent
run_task calls (the scheduler exercises this via concurrent
invocations).
Required Methods§
Sourcefn on_task_started(&self, task: &TaskId)
fn on_task_started(&self, task: &TaskId)
Called once at the start of the run, before any cache work.
Sourcefn on_stdout(&self, task: &TaskId, bytes: &[u8])
fn on_stdout(&self, task: &TaskId, bytes: &[u8])
One chunk of captured stdout bytes. For a cache hit, called exactly once with the recorded stdout in full. For a fresh run, the call shape depends on the observer’s presentation strategy: a buffered observer typically receives a single call with the whole captured stdout; a live observer may receive many sub-line chunks as bytes flow from the pipe.
Sourcefn on_stderr(&self, task: &TaskId, bytes: &[u8])
fn on_stderr(&self, task: &TaskId, bytes: &[u8])
One chunk of captured stderr bytes. Same call shape as
Self::on_stdout.
Sourcefn on_task_finished(&self, task: &TaskId, record: &CompletedRecord)
fn on_task_finished(&self, task: &TaskId, record: &CompletedRecord)
Called once at the end of the run with the run-record
classification. Fires only for tasks the scheduler
admitted into the lookup-then-spawn pipeline; cascade-
skipped tasks surface through
Self::on_task_skipped instead.
Sourcefn on_task_skipped(&self, task: &TaskId, record: &SkipRecord)
fn on_task_skipped(&self, task: &TaskId, record: &SkipRecord)
Called once at the moment the scheduler marks task
cascade-skipped per EXEC-010 / EXEC-011. Fires before
the next admission round; NEVER paired with
Self::on_task_started or Self::on_task_finished
for the same task.
Sourcefn on_task_cancelled(&self, task: &TaskId, record: &CancelledRecord)
fn on_task_cancelled(&self, task: &TaskId, record: &CancelledRecord)
Called once at the moment the cancellation flow records a
terminal state for task per EXEC-012..015. The
CancelledRecord variant distinguishes the three
shapes: an in-flight task that was signalled by the
executor; a cascade descendant of a cancelled task; or a
task drained from state.ready on cancel-fire. For an
in-flight task, Self::on_task_started has already
fired and Self::on_task_finished does NOT fire; for
the other two shapes, no other lifecycle callback fires
for the same task.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".