pub trait Pulse: Stop + Report {
// Required method
fn split(
&self,
execution: Execution,
parts: &[PhaseSpec<'_>],
) -> Result<Vec<Child<'_>>, PlanError>;
// Provided methods
fn record_issue(&self, _error: PlanError) { ... }
fn start(&self) -> Result<(), PlanError> { ... }
fn set_total(&self, _total: Total) -> Result<(), PlanError> { ... }
fn share(&self) -> Result<SharedPulse, PlanError> { ... }
}Expand description
Cancellation, completed work, and nested phase planning, in one value.
A library accepts &dyn Pulse and uses it three ways:
check()asks whether to stop. It is the cheapest call, unless the caller made it run code of its own, as a checkpoint callback does; check once per row, block or tile, not per byte.advance(n)counts finished units;ProgressExt::stepcounts and then checks.splitdeclares weighted children. The library owns the returnedChildhandles and finishes each one. It never finishes the pulse it was given; that pulse belongs to its caller.
Splitting and counting are exclusive: a phase either counts its own units (a leaf) or delegates to children (a branch). Plan before the first report.
Wrappers that add measurement or forwarding implement this trait, so it is open. Methods added in later compatible releases will have default bodies.
§Implementing
A tracker or checkpoint callback adapter from how-far-along usually
suffices. Implementations must keep these rules:
checkandadvancemay run on many threads at once, andadvancemust not block.may_stopandmay_reportreturnfalseonly when that can never change.splitstarts withPhaseSpec::validate_split. It fails withPlanError::AlreadyInUseif this phase already counted work or split, and otherwise returns oneChild::newper part, in order, each checking and counting like any pulse. Children fromChild::inertcannot be stopped or observed, so they suit only parts nobody watches.sharereturns an owned view that checks the same stop, counts into the same phase and plans its children, or fails withPlanError::NotShareable; it never silently drops cancellation.ChildPulse::finishfails withPlanError::UnfinishedChildrenwhile a descendant is unfinished. Completed failed attempts may belong to a successful parent. A dropped unfinished child recordsAbandoned.
Required Methods§
Sourcefn split(
&self,
execution: Execution,
parts: &[PhaseSpec<'_>],
) -> Result<Vec<Child<'_>>, PlanError>
fn split( &self, execution: Execution, parts: &[PhaseSpec<'_>], ) -> Result<Vec<Child<'_>>, PlanError>
Split this phase into weighted children, in declared order.
Returns exactly one Child per part. The caller owns them: pass
&child to code that does the child’s work, then finish the child once
that work has joined. Fails if the parts are invalid, if this phase
already counted work or split, or if the pulse cannot plan children.
Provided Methods§
Sourcefn record_issue(&self, _error: PlanError)
fn record_issue(&self, _error: PlanError)
Record a reporting-protocol problem for optional diagnostics. This never changes cancellation or the operation’s return value. Ordinary sinks may ignore it; diagnostic wrappers retain bounded evidence.
Sourcefn start(&self) -> Result<(), PlanError>
fn start(&self) -> Result<(), PlanError>
Mark this phase running, without counting or ending planning. Implementations without lifecycle observations may ignore this.
Sourcefn set_total(&self, _total: Total) -> Result<(), PlanError>
fn set_total(&self, _total: Total) -> Result<(), PlanError>
Revise a leaf’s denominator without changing completed units or weights. Unsupported implementations return an error instead of losing the update.
Share all pulse capabilities with owned work, but never completion rights.
The SharedPulse is 'static, cloneable and thread-safe, and works
wherever a Stop or Report is expected: give it to a codec context that
stores impl Stop + 'static, a spawned thread, or an async task. Join
such work before finishing the original owner. Unsupported ownership is
explicit; this method never silently replaces cancellation with a no-op.
Implementations§
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".