nobreak 0.1.0

nobreak is a minimal circuit breaker for your functions
Documentation
  • Coverage
  • 21.74%
    5 out of 23 items documented0 out of 16 items with examples
  • Size
  • Source code size: 24.99 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 2.18 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 12s Average build duration of successful builds.
  • all releases: 12s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Repository
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • kjuulh

nobreak

A minimal circuit breaker library for Rust with both sync and async support.

Usage

Async (enabled by default via the tokio feature):

let cb = nobreak::breaker();

let result = cb
    .call_async(|| async {
        do_something().await
    })
    .await
    .map_err(|e| e.into_inner().unwrap())?;

Sync:

let cb = nobreak::breaker();

let result = cb
    .call(|| {
        do_something()
    })
    .map_err(|e| e.into_inner().unwrap())?;

Both use sensible defaults: 5 failure threshold, 2 success threshold for half-open recovery, and a 30s open duration.

The circuit breaker tracks consecutive failures. Once the failure threshold is reached, the circuit opens and subsequent calls are rejected immediately with CircuitError::Open without executing the function. After the open duration elapses, the circuit transitions to half-open and allows calls through again. If enough consecutive successes occur, the circuit closes. If a call fails in half-open, the circuit reopens.

Features

The tokio feature is enabled by default, providing call_async. To use only the sync API:

nobreak = { version = "0.1", default-features = false }

Builder

For more control, use the builder:

use std::time::Duration;

let cb = nobreak::builder()
    .with_failure_threshold(10)
    .with_success_threshold(3)
    .with_open_duration(Duration::from_secs(60))
    .build();

cb.call_async(|| async {
    do_something().await
})
.await?;

Configuration

  • with_failure_threshold(n) — number of consecutive failures before the circuit opens (default: 5)
  • with_success_threshold(n) — number of consecutive successes in half-open state before the circuit closes (default: 2)
  • with_open_duration(dur) — how long the circuit stays open before transitioning to half-open (default: 30s)

Circuit states

  • Closed — normal operation, calls pass through. Consecutive failures are tracked; a success resets the count.
  • Open — calls are rejected immediately with CircuitError::Open. After open_duration elapses, transitions to half-open.
  • Half-open — calls pass through to test recovery. A failure reopens the circuit. Once success_threshold consecutive successes occur, the circuit closes.

Inspect the current state at any time:

let state = cb.state(); // CircuitState::Closed | Open | HalfOpen

Error handling

CircuitError<E> has two variants:

  • Failed { error } — the operation was executed but returned an error
  • Open — the circuit is open; the operation was not executed

Call .into_inner() to extract the underlying error as an Option<E> (returns None for Open).