From b3ca11e2fb4478bc8ced895b94cd8f62e8035595 Mon Sep 17 00:00:00 2001 From: SteveLauC Date: Thu, 5 Sep 2024 11:47:59 +0800 Subject: [PATCH] docs: document custom Sleeper impl (#147) ### What does this PR do Adds an example for user-provided sleeper implementation. Closes #129 --- backon/src/docs/examples/custom_sleeper.md | 43 +++++++++++++++++++ backon/src/lib.rs | 49 +++++++++++++++++++--- 2 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 backon/src/docs/examples/custom_sleeper.md diff --git a/backon/src/docs/examples/custom_sleeper.md b/backon/src/docs/examples/custom_sleeper.md new file mode 100644 index 0000000..1d0fb0e --- /dev/null +++ b/backon/src/docs/examples/custom_sleeper.md @@ -0,0 +1,43 @@ +Let's implement a custom async Sleeper, say you are using Monoio as your async +runtime, you may want to implement it with `monoio::time::sleep()`. If you want +to implement a custom blocking Sleeper, you will find it pretty similar. + +```rust +use std::time::Duration; +use backon::Sleeper; + +/// Sleeper implemented using `monoio::time::sleep()`. +struct MonoioSleeper; + +impl Sleeper for MonoioSleeper { + type Sleep = monoio::time::Sleep; + + fn sleep(&self, dur: Duration) -> Self::Sleep { + monoio::time::sleep(dur) + } +} +``` + +Then you can use it like: + +```rust +use backon::ExponentialBuilder; +use backon::Retryable; +use anyhow::Result; + +async fn fetch() -> Result { + Ok("Hello, World!".to_string()) +} + +#[monoio::main(timer_enabled = true)] +async fn main() -> Result<()> { + let content = fetch + .retry(ExponentialBuilder::default()) + .sleep(MonoioSleeper) + .await?; + + println!("fetch succeeded: {}", content); + Ok(()) +} + +``` \ No newline at end of file diff --git a/backon/src/lib.rs b/backon/src/lib.rs index 4470141..2cac7c7 100644 --- a/backon/src/lib.rs +++ b/backon/src/lib.rs @@ -31,16 +31,53 @@ //! //! # Sleep //! -//! Retry in BackON requires an implementation for sleeping. BackON will accept a [`Sleeper`] to pause for a specified duration. +//! Retry in BackON requires an implementation for sleeping, such an implementation +//! is called a Sleeper, it will implement [`Sleeper`] or [`BlockingSleeper`] depending +//! on if it is going to be used in an asynchronous context. //! -//! BackON employs the following default sleep implementations: +//! ## Default Sleeper //! -//! - `tokio-sleep`: Utilizes [`TokioSleeper`] within a Tokio context in non-wasm32 environments. -//! - `gloo-timers-sleep`: Utilizes [`GlooTimersSleep`] to pause in wasm32 environments. +//! Currently, BackON has 3 built-in Sleeper implementations for different +//! environments, they are gated under their own features, which are enabled +//! by default: //! -//! Users CAN provide a custom implementation if they prefer not to use the default options. +//! | `Sleeper` | feature | Environment | Asynchronous | +//! |---------------------|--------------------|-------------|---------------| +//! | [`TokioSleeper`] | tokio-sleep | non-wasm32 | Yes | +//! | [`GlooTimersSleep`] | gloo-timers-sleep | wasm32 | Yes | +//! | [`StdSleeper`] | std-blocking-sleep | all | No | //! -//! If neither feature is enabled nor a custom implementation is provided, BackON will fallback to an empty sleeper. This will cause a panic in the `debug` profile and do nothing in the `release` profile. +//! ## Custom Sleeper +//! +//! If you do not want to use the built-in Sleeper, you CAN provide a custom +//! implementation, let's implement an asynchronous dummy Sleeper that does +//! not sleep at all. You will find it pretty similar when you implement a +//! blocking one. +//! +//! ``` +//! use std::time::Duration; +//! use backon::Sleeper; +//! +//! /// A dummy `Sleeper` impl that prints then becomes ready! +//! struct DummySleeper; +//! +//! impl Sleeper for DummySleeper { +//! type Sleep = std::future::Ready<()>; +//! +//! fn sleep(&self, dur: Duration) -> Self::Sleep { +//! println!("Hello from DummySleeper!"); +//! std::future::ready(()) +//! } +//! } +//! ``` +//! +//! ## The empty Sleeper +//! +//! If neither feature is enabled nor a custom implementation is provided, BackON +//! will fallback to the empty sleeper, in which case, a compile-time error that +//! `PleaseEnableAFeatureOrProvideACustomSleeper needs to implement Sleeper or +//! BlockingSleeper` will be raised to remind you to choose or bring a real Sleeper +//! implementation. //! //! # Retry //!