Skip to main content

RunObserver

Trait RunObserver 

Source
pub trait RunObserver: Send + Sync {
Show 21 methods // Required methods fn phase_starting( &self, scene_node_id: SceneNodeId, name: &str, labels: &str, op_templates: usize, total_cycles: u64, concurrency: usize, ); fn phase_completed( &self, scene_node_id: SceneNodeId, name: &str, labels: &str, duration_secs: f64, ); fn phase_failed( &self, scene_node_id: SceneNodeId, name: &str, labels: &str, error: &str, ); fn phase_progress(&self, update: &PhaseProgressUpdate); fn run_finished(&self); fn log(&self, level: LogLevel, message: &str); // Provided methods fn sysmon_update(&self, _sample: &SysmonSample) { ... } fn session_dir_ready(&self, _dir: &Path) { ... } fn op_starting(&self, _parent_phase: SceneNodeId, _op_name: &str) { ... } fn op_completed( &self, _parent_phase: SceneNodeId, _op_name: &str, _duration_secs: f64, ) { ... } fn op_measure( &self, _parent_phase: SceneNodeId, _op_name: &str, _text: &str, ) { ... } fn op_failed( &self, _parent_phase: SceneNodeId, _op_name: &str, _error: &str, ) { ... } fn phase_render_attach(&self, _handle: PhaseRenderHandle) { ... } fn log_tagged(&self, level: LogLevel, _tag: EventTag, message: &str) { ... } fn suppresses_stderr(&self) -> bool { ... } fn live_suppress_flag(&self) -> Option<Arc<AtomicBool>> { ... } fn reporter(&self) -> Option<Box<dyn Reporter>> { ... } fn reporters(&self) -> Vec<(Duration, Box<dyn Reporter>)> { ... } fn cadences(&self) -> Option<Cadences> { ... } fn on_metrics_query(&self, _query: Arc<MetricsQuery>) { ... } fn scenario_pre_mapped(&self, _tree: &SceneTree) { ... }
}
Expand description

Lifecycle events from the executor.

Required Methods§

Source

fn phase_starting( &self, scene_node_id: SceneNodeId, name: &str, labels: &str, op_templates: usize, total_cycles: u64, concurrency: usize, )

A phase is about to start executing.

op_templates is the count of op definitions in the phase (typically 1 for query workloads). total_cycles is the number of times the stanza will iterate. Both are reported because they answer different questions: the first describes the shape of the phase, the second describes the amount of work it represents.

scene_node_id is the phase’s dispatch-time crate::scene_tree::SceneNodeId (SRD-100 P1c) — the stable row key for lifecycle routing. Observers flip that node directly instead of re-matching by (name, status) in DFS order, which races under concurrent same-name dispatch (sweep cells, comprehension iterations, daemon+foreground).

Source

fn phase_completed( &self, scene_node_id: SceneNodeId, name: &str, labels: &str, duration_secs: f64, )

A phase completed successfully. scene_node_id keys the node to flip (see Self::phase_starting).

Source

fn phase_failed( &self, scene_node_id: SceneNodeId, name: &str, labels: &str, error: &str, )

A phase failed. scene_node_id keys the node to flip (see Self::phase_starting).

Source

fn phase_progress(&self, update: &PhaseProgressUpdate)

Update live metrics for the active phase (called at progress tick rate).

Source

fn run_finished(&self)

The entire run is complete.

Source

fn log(&self, level: LogLevel, message: &str)

Diagnostic log message. Routed to stderr in CLI mode, to a ring buffer in TUI mode. All eprintln! in the runtime should go through this instead.

Provided Methods§

Source

fn sysmon_update(&self, _sample: &SysmonSample)

A completed sysmon sample window (session-level host utilization). Display surfaces override; everything else ignores it.

Source

fn session_dir_ready(&self, _dir: &Path)

The session directory now exists. Display surfaces that persist a transcript open it here — the runner creates the directory well after the observer is built, so this is the first moment the path is known.

Source

fn op_starting(&self, _parent_phase: SceneNodeId, _op_name: &str)

SRD-63 — an op-level execution leaf became visible (readout: visible, enabled by the readout wrapper). Nests under parent_phase in the hierarchic status view; the consumer assigns its sequence within the phase from arrival order. Default no-op so observers that don’t render op-level leaves (and the zero-cost non-readout path) are unaffected.

Source

fn op_completed( &self, _parent_phase: SceneNodeId, _op_name: &str, _duration_secs: f64, )

An op-level execution leaf completed. duration_secs is the op’s own cumulative execution time. Default no-op.

Source

fn op_measure(&self, _parent_phase: SceneNodeId, _op_name: &str, _text: &str)

The op’s KEY MEASURABLE, rendered from its measure: template at completion — “12 sstables”, “1.4 GiB”, “98.1%”.

A leaf row already carries how LONG a step took; this carries what it actually produced, which is the number a reader is usually after. Sent as its own hook (rather than widening op_completed) so every existing observer keeps compiling and ignoring it costs nothing.

Source

fn op_failed(&self, _parent_phase: SceneNodeId, _op_name: &str, _error: &str)

An op-level execution leaf failed. Default no-op.

Source

fn phase_render_attach(&self, _handle: PhaseRenderHandle)

SRD-100 P2 — attach the per-phase PhaseRenderHandle to the live display fold, once, after the activity’s metrics/binder exist (the executor calls this on-task at progress-setup time). Observers that own a run-state actor (TUI / log-only) route it to an AttachPhaseRender mutation so the consumer can fold active_phases and re-derive each phase’s status line itself; the no-op default is correct for surfaces with no live status fold (Stderr / Headless).

Source

fn log_tagged(&self, level: LogLevel, _tag: EventTag, message: &str)

Log a message carrying an explicit EventTag. The default ignores the tag and delegates to Self::log — correct for every observer whose surface treats all events alike. Observers that feed a tag-aware sink (the run-state actor ring) override this to retain both axes.

Source

fn suppresses_stderr(&self) -> bool

Whether to suppress the inline stderr progress line (because the TUI is handling display).

Source

fn live_suppress_flag(&self) -> Option<Arc<AtomicBool>>

Optional shared flag mirroring Self::suppresses_stderr that the runner threads into long-lived components (e.g. the activity’s inline status thread) so they can react to dismissal mid-run rather than honoring a snapshot taken at construction. When None, the activity uses a fresh AtomicBool(false) (never suppress). Implementations that go through a TUI (and only those) typically expose their internal “tui_active” flag here.

Source

fn reporter(&self) -> Option<Box<dyn Reporter>>

Optional reporter to register on the metrics scheduler. The runner calls this once during setup. Return None for observers that don’t need metrics frames (like StderrObserver).

Kept for back-compat; for observers that want multiple reporters at different cadences, override [reporters] instead — the default impl forwards this single reporter as the base cadence.

Source

fn reporters(&self) -> Vec<(Duration, Box<dyn Reporter>)>

Multiple reporters with explicit cadences. The runner calls this once during setup. Each (interval, reporter) entry is registered with the scheduler at that interval. The default implementation returns whatever [reporter] produced at the base 1s cadence, so existing observers work unchanged.

Source

fn cadences(&self) -> Option<Cadences>

User-declared cadences for this observer’s consumers (SRD-42).

When present, the runner uses these to plan the cadence tree passed to the scheduler’s nmbrs_metrics::cadence_reporter::CadenceReporter. The reporter writes all windowed snapshots into a single store that every consumer reads through nmbrs_metrics::metrics_query::MetricsQuery.

Observers that don’t need windowed views (e.g. StderrObserver) return None and the runner falls back to Cadences::defaults().

Source

fn on_metrics_query(&self, _query: Arc<MetricsQuery>)

Callback invoked once the runner has built the shared nmbrs_metrics::metrics_query::MetricsQuery. Observers that render metrics (TUI, CLI status) capture this handle to read cadence windows, now values, and session-lifetime aggregates.

Source

fn scenario_pre_mapped(&self, _tree: &SceneTree)

Pre-populated scenario tree.

Called once before execution begins with the full crate::scene_tree::SceneTree — synthetic root, every concrete phase, and every scope header (for_each, for_combinations, do_while, do_until) wired up by parent / children pointers.

The TUI uses this to show all phases as Pending from the start; renderers that want hierarchical features (collapse, scope-level aggregate status) walk the tree directly. The callee may store the tree (e.g. behind an RwLock) and mutate node statuses in place via the lifecycle callbacks.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§