/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tower-0.5.2/src/buffer/layer.rs
Line | Count | Source |
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 |
36 | 0 | pub const fn new(bound: usize) -> Self { |
37 | 0 | BufferLayer { |
38 | 0 | bound, |
39 | 0 | _p: PhantomData, |
40 | 0 | } |
41 | 0 | } |
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<Request, S::Future>; |
52 | | |
53 | 0 | fn layer(&self, service: S) -> Self::Service { |
54 | 0 | Buffer::new(service, self.bound) |
55 | 0 | } |
56 | | } |
57 | | |
58 | | impl<Request> fmt::Debug for BufferLayer<Request> { |
59 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
60 | 0 | f.debug_struct("BufferLayer") |
61 | 0 | .field("bound", &self.bound) |
62 | 0 | .finish() |
63 | 0 | } |
64 | | } |
65 | | |
66 | | impl<Request> Clone for BufferLayer<Request> { |
67 | 0 | fn clone(&self) -> Self { |
68 | 0 | Self { |
69 | 0 | bound: self.bound, |
70 | 0 | _p: PhantomData, |
71 | 0 | } |
72 | 0 | } |
73 | | } |
74 | | |
75 | | impl<Request> Copy for BufferLayer<Request> {} |