Skip to main content

tower_batch/
layer.rs

1use std::{fmt, marker::PhantomData, time::Duration};
2
3use tower::{layer::Layer, Service};
4
5use super::{service::Batch, BatchControl};
6
7/// A [`Layer`] that wraps an inner service with [`Batch`].
8///
9/// The background worker is spawned on the default Tokio executor, so
10/// this layer can only be used on the Tokio runtime.
11///
12/// See the [module documentation](crate) for the full lifecycle and error
13/// semantics.
14pub struct BatchLayer<Request> {
15    size: usize,
16    time: Duration,
17    _p: PhantomData<fn(Request)>,
18}
19
20impl<Request> BatchLayer<Request> {
21    /// Creates a new [`BatchLayer`].
22    ///
23    /// * `size` – the maximum number of items per batch.
24    /// * `time` – the maximum duration before a batch is flushed.
25    #[must_use]
26    pub fn new(size: usize, time: Duration) -> Self {
27        Self {
28            size,
29            time,
30            _p: PhantomData,
31        }
32    }
33}
34
35impl<S, Request> Layer<S> for BatchLayer<Request>
36where
37    S: Service<BatchControl<Request>> + Send + 'static,
38    S::Future: Send,
39    S::Error: Into<crate::BoxError> + Send + Sync,
40    Request: Send + 'static,
41{
42    type Service = Batch<S, Request>;
43
44    fn layer(&self, service: S) -> Self::Service {
45        Batch::new(service, self.size, self.time)
46    }
47}
48
49impl<Request> fmt::Debug for BatchLayer<Request> {
50    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51        f.debug_struct("BatchLayer")
52            .field("size", &self.size)
53            .field("time", &self.time)
54            .finish()
55    }
56}