Crate steppe

Source
Expand description

§Steppe

This crate is used to track the progress of a task through multiple steps composed of multiple states.

The objectives are:

  • Have a very simple API to describe the steps composing a task. (create the steps and update the progress)
  • Provide an easy way to display the current progress while the process is running.
  • Provide a way to get the accumulated durations of each steps to quickly see the bottleneck.
  • Don’t slow down the main process too much.

The crate is composed of only 2 parts:

  • The Progress struct that is used to track the progress of the task.
  • The Step trait that is used to describe the steps composing a task.

The Progress struct is thread-safe, can be cloned cheaply and shared everywhere. While a thread is updating it another can display what we’re doing. The Step trait is used to describe the steps composing a task.

The API of the Progress is made of three parts:

Since creating Steps is a bit tedious, you can use the following helpers:

use std::sync::atomic::Ordering;
use steppe::{make_enum_progress, make_atomic_progress, Progress, Step, NamedStep, AtomicSubStep};
 
// This will create a new enum that implements the `Step` trait automatically. Take care it's very case sensitive.
make_enum_progress! {
    pub enum TamosDay {
        PetTheDog,
        WalkTheDog,
        TypeALotOnTheKeyboard,
        WalkTheDogAgain,
    }
}
 
// This create a new struct that implement the `Step` trait automatically.
// It's displayed as "key strokes" and we cannot change its name.
make_atomic_progress!(KeyStrokes alias AtomicKeyStrokesStep => "key strokes");
 
let mut progress = Progress::default();
progress.update(TamosDay::PetTheDog); // We're at 0/4 and 0% of completion
progress.update(TamosDay::WalkTheDog); // We're at 1/4 and 25% of completion
 
progress.update(TamosDay::TypeALotOnTheKeyboard); // We're at 2/4 and 50% of completion
let (atomic, key_strokes) = AtomicKeyStrokesStep::new(1000);
progress.update(key_strokes);
// Here we enqueued a new step that have 1000 total states. Since we don't want to take a lock everytime
// we type on the keyboard we're instead going to increase an atomic without taking the mutex.

atomic.fetch_add(500, Ordering::Relaxed);
// If we fetch the progress at this point it should be exactly between 50% and 75%.
 
progress.update(TamosDay::WalkTheDogAgain); // We're at 3/4 and 75% of completion
// By enqueuing this new step the progress is going to drop everything that was pushed after the `TamosDay` type was pushed.

Macros§

make_atomic_progress
This macro is used to create a new atomic progress step quickly.
make_enum_progress
Helper to create a new enum that implements the Step trait. It’s useful when we’re just going to move from one state to another.

Structs§

AtomicSubStep
Structure to quickly define steps that need very quick, lockless updating of their current step. You can use this struct if:
Progress
The main struct of the crate. It stores the current steps we’re processing. It also contains the durations of each steps.
ProgressStepView
The view of the individual steps.
ProgressView
The returned view of the progress.
VariableNameStep
Used when the name can change but it’s still the same step. To avoid conflicts on the TypeId, create a unique type every time you use this step:

Traits§

NamedStep
This trait lets you use the AtomicSubStep defined right below. The name must be a const that never changed but that can’t be enforced by the type system because it make the trait non object-safe. By forcing the Default trait + the &’static str we make it harder to miss-use the trait.
Step
The main trait of the crate. That describes an unit of works.