1 use super::service::Buffer;
2 use std::{fmt, marker::PhantomData};
3 use tower_layer::Layer;
4 use tower_service::Service;
5 
6 /// Adds an mpsc buffer in front of an inner service.
7 ///
8 /// The default Tokio executor is used to run the given service,
9 /// which means that this layer can only be used on the Tokio runtime.
10 ///
11 /// See the module documentation for more details.
12 pub struct BufferLayer<Request> {
13     bound: usize,
14     _p: PhantomData<fn(Request)>,
15 }
16 
17 impl<Request> BufferLayer<Request> {
18     /// Creates a new [`BufferLayer`] with the provided `bound`.
19     ///
20     /// `bound` gives the maximal number of requests that can be queued for the service before
21     /// backpressure is applied to callers.
22     ///
23     /// # A note on choosing a `bound`
24     ///
25     /// When [`Buffer`]'s implementation of [`poll_ready`] returns [`Poll::Ready`], it reserves a
26     /// slot in the channel for the forthcoming [`call`]. However, if this call doesn't arrive,
27     /// this reserved slot may be held up for a long time. As a result, it's advisable to set
28     /// `bound` to be at least the maximum number of concurrent requests the [`Buffer`] will see.
29     /// If you do not, all the slots in the buffer may be held up by futures that have just called
30     /// [`poll_ready`] but will not issue a [`call`], which prevents other senders from issuing new
31     /// requests.
32     ///
33     /// [`Poll::Ready`]: std::task::Poll::Ready
34     /// [`call`]: crate::Service::call
35     /// [`poll_ready`]: crate::Service::poll_ready
new(bound: usize) -> Self36     pub fn new(bound: usize) -> Self {
37         BufferLayer {
38             bound,
39             _p: PhantomData,
40         }
41     }
42 }
43 
44 impl<S, Request> Layer<S> for BufferLayer<Request>
45 where
46     S: Service<Request> + Send + 'static,
47     S::Future: Send,
48     S::Error: Into<crate::BoxError> + Send + Sync,
49     Request: Send + 'static,
50 {
51     type Service = Buffer<S, Request>;
52 
layer(&self, service: S) -> Self::Service53     fn layer(&self, service: S) -> Self::Service {
54         Buffer::new(service, self.bound)
55     }
56 }
57 
58 impl<Request> fmt::Debug for BufferLayer<Request> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result59     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
60         f.debug_struct("BufferLayer")
61             .field("bound", &self.bound)
62             .finish()
63     }
64 }
65 
66 impl<Request> Clone for BufferLayer<Request> {
clone(&self) -> Self67     fn clone(&self) -> Self {
68         Self {
69             bound: self.bound,
70             _p: PhantomData,
71         }
72     }
73 }
74 
75 impl<Request> Copy for BufferLayer<Request> {}
76