Skip to main content

tower_retry_plus/
layer.rs

1use crate::{Retry, RetryConfig};
2use std::sync::Arc;
3use tower::Layer;
4
5/// A Tower [`Layer`] that applies retry logic to a service.
6///
7/// This layer wraps a service with retry middleware that automatically
8/// retries failed requests according to the configured policy.
9///
10/// # Examples
11///
12/// ```
13/// use tower_retry_plus::RetryConfig;
14/// use tower::ServiceBuilder;
15/// use std::time::Duration;
16///
17/// # #[derive(Debug, Clone)]
18/// # struct MyError;
19/// # async fn example() {
20/// let retry_layer: tower_retry_plus::RetryLayer<MyError> = RetryConfig::builder()
21///     .max_attempts(5)
22///     .exponential_backoff(Duration::from_millis(100))
23///     .build()
24///     .layer();
25///
26/// let service = ServiceBuilder::new()
27///     .layer(retry_layer)
28///     .service(my_service());
29/// # }
30/// # fn my_service() -> impl tower::Service<String, Response = String, Error = MyError> {
31/// #     tower::service_fn(|req: String| async move { Ok::<_, MyError>(req) })
32/// # }
33/// ```
34#[derive(Clone)]
35pub struct RetryLayer<E> {
36    config: Arc<RetryConfig<E>>,
37}
38
39impl<E> RetryLayer<E> {
40    /// Creates a new `RetryLayer` with the given configuration.
41    pub fn new(config: RetryConfig<E>) -> Self {
42        Self {
43            config: Arc::new(config),
44        }
45    }
46}
47
48impl<S, E> Layer<S> for RetryLayer<E>
49where
50    E: Clone,
51{
52    type Service = Retry<S, E>;
53
54    fn layer(&self, service: S) -> Self::Service {
55        Retry::new(service, Arc::clone(&self.config))
56    }
57}