Skip to main content

Supervisor

Trait Supervisor 

Source
pub trait Supervisor:
    Send
    + Sync
    + 'static {
    // Required methods
    fn name(&self) -> Name;
    fn child(&self, label: &'static str) -> Self;
    fn with_attribute(self, key: &'static str, value: impl Display) -> Self;
}
Expand description

Interface to track task hierarchy and identity.

Required Methods§

Source

fn name(&self) -> Name

Return the current label prefix and attributes.

Source

fn child(&self, label: &'static str) -> Self

Create a named child context with a new supervision-tree node.

This appends label to the current metric prefix and creates a child in the supervision tree. Use static role names like "engine", "worker", or "resolver". Dynamic values belong in Supervisor::with_attribute so metric names remain bounded.

Labels must start with [a-zA-Z] and contain only [a-zA-Z0-9_]. Runtime-reserved metric prefixes must not be used.

Source

fn with_attribute(self, key: &'static str, value: impl Display) -> Self

Add a key-value attribute to this context’s identity.

Attributes are attached to metrics registered in this context and any child contexts. Unlike Supervisor::child, attributes do not affect metric names and do not create a supervision-tree edge. This makes them the right place for dynamic values like epochs, rounds, shards, or peer identifiers.

Keys must start with [a-zA-Z] and contain only [a-zA-Z0-9_]. Values can be any string. If the key already exists, its value is replaced.

context
  |-- child("orchestrator")
        |-- with_attribute("epoch", "5")
              |-- counter: votes      -> orchestrator_votes{epoch="5"}
              |-- counter: proposals  -> orchestrator_proposals{epoch="5"}
              |-- child("engine")
                    |-- gauge: height -> orchestrator_engine_height{epoch="5"}

This pattern avoids wrapping every metric in a Family and avoids putting dynamic values in metric names like orchestrator_epoch_5_votes.

Attributes do not reduce cardinality. N epochs still means N time series. They just make metrics easier to query, filter, and aggregate.

§Family Label Conflicts

When using Family metrics, avoid attribute keys that match the family’s label field names. A conflict produces duplicate labels in the encoded output, which is invalid Prometheus format.

#[derive(EncodeLabelSet)]
struct Labels { env: String }

// Bad: attribute "env" conflicts with Family field "env".
let ctx = context.child("api").with_attribute("env", "prod");
let family: Family<Labels, Counter> = Family::default();
ctx.register("requests", "help", family);

// Good: use distinct names.
let ctx = context.child("api").with_attribute("region", "us_east");
§Querying The Latest Attribute

To query the latest attribute value dynamically, create a gauge to track the current value:

let latest_epoch = context
    .child("orchestrator")
    .register("latest_epoch", "current epoch", Gauge::default());
latest_epoch.set(current_epoch);

A dashboard can then query max(orchestrator_latest_epoch) and use the result as a variable in queries such as consensus_engine_votes_total{epoch="$latest_epoch"}.

Dyn Compatibility§

This trait is not dyn compatible.

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

Implementors§

Source§

impl Supervisor for commonware_runtime::deterministic::Context

Source§

impl Supervisor for commonware_runtime::tokio::Context