Skip to main content

RunObserver

Trait RunObserver 

Source
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 buffered observer collects the chunks per task and emits one contiguous block to the parent process on RunObserver::on_task_finished.
  • A live observer 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§

Source

fn on_task_started(&self, task: &TaskId)

Called once at the start of the run, before any cache work.

Source

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.

Source

fn on_stderr(&self, task: &TaskId, bytes: &[u8])

One chunk of captured stderr bytes. Same call shape as Self::on_stdout.

Source

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.

Source

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.

Source

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".

Implementors§

Source§

impl<O, E> RunObserver for BufferedOutputObserver<O, E>
where O: Write + Send, E: Write + Send,

Source§

impl<O, E> RunObserver for LiveOutputObserver<O, E>
where O: Write + Send, E: Write + Send,