Skip to main content

Crate how_far_along

Crate how_far_along 

Source
Expand description

§how-far-along CI crates.io lib.rs docs.rs license

Guide and interactive examples · API reference

Tracking and observation for how-far. This crate records declared work; applications choose when to observe it. It starts no threads and reads no clocks.

[dependencies]
how-far-along = "0.1.0"

The library accepts &dyn Pulse; the application owns the tree and its final result. Keep an observer for your display, then hand the result back before ?:

use how_far_along::{prelude::*, Phase, PulseTree, StopReason, Total, Unstoppable};

fn checksum(bytes: &[u8], pulse: &dyn Pulse) -> Result<u64, StopReason> {
    pulse.check()?;
    let mut sum = 0;
    for &byte in bytes {
        sum += u64::from(byte);
        pulse.step(1)?;
    }
    Ok(sum)
}

let tree = PulseTree::new(Phase::new("checksum", Total::Exact(3)), Unstoppable);
let observer = tree.observer();
let result = checksum(&[1, 2, 3], &tree).finish_phase(tree)?;
assert_eq!(result, 6);
assert_eq!(observer.snapshot().fraction(), Some(1.0));

Replace Unstoppable with your application’s stop token. The library’s code stays the same. The integration guide shows cancellation callbacks, nested stages and display smoothing.

Every phase starts Status::NotStarted, becomes Running when entered or reported to, and eventually becomes Finished(Outcome). Outcomes distinguish Succeeded, Failed, Cancelled, Skipped, NotRun, and Abandoned. A successful parent may retain a failed attempt: the library’s result decides whether it recovered. completion_inferred identifies outcomes resolved by the parent or a plan helper, rather than explicitly reported by that child.

A result handoff freezes the parent’s observation. Started but uncompleted children become abandoned; untouched children are skipped on success and not run on failure. Retained child owners can close later but cannot rewrite that frozen parent observation. Join workers first. Drop supplies abandonment, never an inferred successful result.

Observer::summary() reads fraction, unresolved share and status without allocating. snapshot() copies the tree. try_summary / try_snapshot avoid waiting on standard metadata locks; on no_std they enter the host’s critical section and do not promise wait-free access. Counting never locks metadata. Weighted parents show known progress even while other stages have unknown totals. Unknown children contribute zero but keep their assigned weight; unresolved_fraction exposes their reserved share. A leaf with an unknown or overflowed denominator still returns None. Fractions can regress after total revisions. Success discharges a parent’s obligation without rewriting failed attempts.

The only default feature is std. Snapshot JSON, WithStop, FnPulse and lazy Checkpoint are always available. With defaults disabled, tracking uses alloc, pointer atomics, and the application’s critical-section provider. That provider must exclude every participating core. Native-width counters saturate and expose overflow on targets without 64-bit atomics. Callbacks need neither std nor 64-bit atomics. Callback state belongs only to callback-backed pulses; ordinary PulseTree nodes have no callback field or dispatch branch. The stable, opt-in smooth feature adds ProgressSmoother, which smooths a display’s fraction between reports at each running stage’s own pace; it needs neither std nor a clock of its own.

Callbacks run at checkpoints, never from counting, completion or Drop. Use poll::LocalPoller for UI-thread or borrowed callbacks. Shared workers retain full capabilities through share(); completion rights remain with the owner.

Only selected how-far author-facing types and its trait prelude are re-exported. Implementor and checked-runner types are imported directly from how_far. Profiling and tuning belong in how_far_really::{profile, diagnostics}; neither that crate nor its types are re-exported here.

ⓘ
use how_far_along::diagnostics::DiagnosticPulse;

Tracking JSON uses schema version 2 (NotStarted and inferred-completion evidence). See the example application and design and API boundaries.

The tested integration guide connects library code, caller-owned completion, diagnostics and display smoothing.

Modules§

ext
Report adapters. Importing this trait is optional.
poll
Callbacks over snapshots, dispatched when you poll.
prelude
The traits whose methods library code calls: use how_far::prelude::*;.

Structs§

Checkpoint
A checkpoint’s lazy observation. No tree walk occurs unless requested.
Child
A planned child phase, owned by the code that called Pulse::split.
FnPulse
A tracked root with a callback at each cancellation checkpoint. Reports, phase finishes, and Drop never invoke the callback. step invokes it once; call Paced::finish to flush and check a final partial batch. Callbacks may overlap on different workers; no internal lock is held. The first stop reason wins. Already-running callbacks may complete. For thread-affine UI captures use poll::LocalPoller with an Observer.
NodeId
A phase’s identity within one job. The root is NodeId::ROOT; children are numbered in planning order. Profiling spans use it to refer to phases.
Observer
A read-only, cloneable view of a phase and its subtree, usable from any thread. Holding one keeps the job’s records alive.
Paced
Counts completed work locally and reaches its pulse once every every units: it reports the units counted so far, then checks for cancellation.
Phase
The owner of one phase: its plan, its counter, and its outcome.
PhaseSpec
One child in a split: a name, a weight relative to its siblings, a total, and optionally a unit name and an execution model.
Phases
A fixed set of owned phases, selected by index rather than automatic sequence. A failed attempt leaves other phases available. The library decides whether to recover, retry, or propagate its error. Hand the final result to complete to resolve untouched phases; Drop without that handoff records abandonment.
ProgressSmoother
Smooths a polled tree’s fraction between reports, for display.
PulseTree
Owns the root of a tracked operation. Workers borrow it or use share(). Finish after joining workers. Dropping this owner freezes abandonment even when non-owning shared views remain alive.
Reporter
A cloneable, thread-safe counter for one phase, from Phase::reporter.
SharedPulse
An owned, cloneable pulse that retains planning and cancellation capabilities. The original phase owner alone may finish it. Requires pointer atomics.
Snapshot
A point-in-time copy of a phase and its subtree.
Stage
One active sequential stage, borrowing its plan until result handoff.
StageKey
A reservation identifying one stage in one Stages::define plan.
Stages
Sequential work returning the library’s ordinary Result<T, E>.
StopOnly
Cancellation without progress: a pulse made from any Stop.
Summary
A lightweight observation of weighted progress, without names or allocations.
Unstoppable
A Stop implementation that never stops (no cooperative cancellation).
WithStop
Adds or replaces a pulse’s checkpoint policy, including through descendants.

Enums§

Execution
How a phase’s work is scheduled. Declaring it schedules nothing.
Outcome
How a phase ended. Reaching a count total is not an outcome.
PlanError
A phase plan that cannot be applied, or a lifecycle step out of order.
Status
Lifecycle state, independent of the counted fraction.
StopReason
Why an operation was stopped.
Total
The denominator for completed work in one phase.

Statics§

NoPulse
Never stops and discards reports, including in every nested phase.

Traits§

AsStopReason
The StopReason an error represents, if it represents one.
Complete
An owner that can record a result without changing the operation’s result. Reporting problems are diagnostic evidence, never replacement work errors.
ProgressExt
Checkpoints for anything that both checks cancellation and counts work, including &dyn Pulse, Child, and ProgressWithStop.
Pulse
Cancellation, completed work, and nested phase planning, in one value.
Report
A sink for completed units of work.
ResultExt
The explicit boundary where a normal Rust result completes its phase owner.
Stop
Cooperative cancellation check.