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