noretry
A simple retry library for Rust with both sync and async support.
Usage
Async (enabled by default via the tokio feature):
let result = noretry::retry_async(|| async {
do_something().await
})
.await
.map_err(|e| e.into_inner())?;
Sync:
let result = noretry::retry(|| {
do_something()
})
.map_err(|e| e.into_inner())?;
Both use sensible defaults: 3 attempts, exponential backoff, 100ms initial delay, 30s cap, and jitter.
Errors returned from the closure are automatically treated as transient (retryable) via the From impl on Retryable. Use ? as normal and retries happen transparently.
Features
The tokio feature is enabled by default, providing retry_async and run_async. To use only the sync API:
noretry = { version = "0.1", default-features = false }
Builder
For more control, use the builder with run (sync) or run_async:
noretry::builder()
.with_max_attempts(5)
.with_linear_backoff()
.build()
.run_async(|| async {
do_something().await
})
.await?;
Backoff strategies
Exponential backoff (default):
noretry::builder()
.with_exponential_backoff()
.build()
Linear backoff:
noretry::builder()
.with_linear_backoff()
.build()
Both strategies support configurable initial delay, max delay cap, and jitter (enabled by default):
use std::time::Duration;
noretry::builder()
.with_initial_delay(Duration::from_millis(200))
.with_max_delay(Duration::from_secs(10))
.with_jitter(false)
.build()
Permanent errors
If an error should not be retried, mark it as permanent using map_err:
use noretry::Retryable;
noretry::builder()
.build()
.run_async(|| async {
do_something()
.await
.map_err(Retryable::permanent)?
})
.await;
The result is a RetryError::Permanent or RetryError::Exhausted, both of which carry the original error. Call .into_inner() to extract it.