pub trait ProgressExt: Stop + Report {
// Provided methods
fn step(&self, completed: u64) -> Result<(), StopReason> { ... }
fn live(&self) -> Option<&Self> { ... }
fn split_array<const N: usize>(
&self,
execution: Execution,
parts: [PhaseSpec<'_>; N],
) -> Result<[Child<'_>; N], PlanError>
where Self: Pulse { ... }
}Expand description
Checkpoints for anything that both checks cancellation and counts work,
including &dyn Pulse, Child, and
ProgressWithStop.
Provided Methods§
Sourcefn step(&self, completed: u64) -> Result<(), StopReason>
fn step(&self, completed: u64) -> Result<(), StopReason>
Count completed finished units, then check for cancellation.
Work finished before a stop request is still counted. Check once
before a loop and step after each finished unit or batch; check()
alone is the stop-only checkpoint. With
NoPulse, step makes no call: the pulse is
recognized by its address, a comparison a loop moves out of its body.
Sourcefn live(&self) -> Option<&Self>
fn live(&self) -> Option<&Self>
The live pulse: this value, or None when it can neither stop nor
report.
step already skips NoPulse
without a call. live extends that to any pulse whose may_stop and
may_report both return false, for the price of asking it once. Call
it once before a hot loop. Option<&P> implements Stop and Report,
so check, advance and step work on the result: they forward when
the pulse may stop or report, and cost a branch, which a loop hoists,
instead of a call when it can do neither. may_stop and may_report
return false only for permanent no-ops, so gating early never drops a
report or a stop request.
use how_far::prelude::*;
fn decode(rows: &[Vec<u8>], pulse: &dyn Pulse) -> Result<u64, how_far::StopReason> {
let pulse = pulse.live();
pulse.check()?;
let mut sum = 0;
for row in rows {
sum += row.iter().map(|&b| u64::from(b)).sum::<u64>();
pulse.step(1)?;
}
Ok(sum)
}
assert!(how_far::NoPulse.live().is_none());
assert_eq!(decode(&[vec![1, 2], vec![3]], &how_far::NoPulse), Ok(6));Sourcefn split_array<const N: usize>(
&self,
execution: Execution,
parts: [PhaseSpec<'_>; N],
) -> Result<[Child<'_>; N], PlanError>where
Self: Pulse,
fn split_array<const N: usize>(
&self,
execution: Execution,
parts: [PhaseSpec<'_>; N],
) -> Result<[Child<'_>; N], PlanError>where
Self: Pulse,
Pulse::split into exactly N children, returned as an array.
use how_far::{Execution, NoPulse, PhaseSpec, ProgressExt, Total};
let [left, right] = NoPulse.split_array(Execution::ForkJoin, [
PhaseSpec::new("left", 1, Total::Exact(10)),
PhaseSpec::new("right", 1, Total::Exact(10)),
])?;§Panics
If the pulse breaks the Pulse::split contract by returning a
different number of children than parts.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".