tower_resilience_adaptive/
layer.rs1use crate::{AdaptiveService, Algorithm, ConcurrencyAlgorithm};
4use std::sync::Arc;
5use tower_layer::Layer;
6
7pub struct AdaptiveLimiterLayer<A> {
26 algorithm: Arc<A>,
27}
28
29impl<A> AdaptiveLimiterLayer<A>
30where
31 A: ConcurrencyAlgorithm,
32{
33 pub fn new(algorithm: A) -> Self {
35 Self {
36 algorithm: Arc::new(algorithm),
37 }
38 }
39
40 pub fn builder() -> AdaptiveLimiterLayerBuilder {
42 AdaptiveLimiterLayerBuilder::new()
43 }
44}
45
46impl<A> Clone for AdaptiveLimiterLayer<A> {
47 fn clone(&self) -> Self {
48 Self {
49 algorithm: Arc::clone(&self.algorithm),
50 }
51 }
52}
53
54impl<S, A> Layer<S> for AdaptiveLimiterLayer<A>
55where
56 A: ConcurrencyAlgorithm + 'static,
57{
58 type Service = AdaptiveService<S, A>;
59
60 fn layer(&self, service: S) -> Self::Service {
61 AdaptiveService::new(service, Arc::clone(&self.algorithm))
62 }
63}
64
65pub struct AdaptiveLimiterLayerBuilder {
67 _private: (),
68}
69
70impl AdaptiveLimiterLayerBuilder {
71 fn new() -> Self {
72 Self { _private: () }
73 }
74
75 pub fn aimd(self) -> crate::AimdBuilder {
77 crate::Aimd::builder()
78 }
79
80 pub fn vegas(self) -> crate::VegasBuilder {
82 crate::Vegas::builder()
83 }
84}
85
86pub trait IntoLayer {
88 type Algorithm: ConcurrencyAlgorithm;
90
91 fn into_layer(self) -> AdaptiveLimiterLayer<Self::Algorithm>;
93}
94
95impl IntoLayer for crate::Aimd {
96 type Algorithm = crate::Aimd;
97
98 fn into_layer(self) -> AdaptiveLimiterLayer<Self::Algorithm> {
99 AdaptiveLimiterLayer::new(self)
100 }
101}
102
103impl IntoLayer for crate::Vegas {
104 type Algorithm = crate::Vegas;
105
106 fn into_layer(self) -> AdaptiveLimiterLayer<Self::Algorithm> {
107 AdaptiveLimiterLayer::new(self)
108 }
109}
110
111impl IntoLayer for Algorithm {
112 type Algorithm = Algorithm;
113
114 fn into_layer(self) -> AdaptiveLimiterLayer<Self::Algorithm> {
115 AdaptiveLimiterLayer::new(self)
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122 use crate::Aimd;
123 use std::time::Duration;
124
125 #[test]
126 fn test_layer_creation() {
127 let algorithm = Aimd::builder()
128 .initial_limit(10)
129 .latency_threshold(Duration::from_millis(100))
130 .build();
131 let layer = AdaptiveLimiterLayer::new(algorithm);
132 let _ = layer.clone();
133 }
134
135 #[test]
136 fn test_into_layer() {
137 let layer = Aimd::builder().initial_limit(10).build().into_layer();
138 let _ = layer.clone();
139 }
140}