44use bytes:: BytesMut ;
55use linkerd_error:: Error ;
66use linkerd_io as io;
7- use linkerd_stack:: { layer, NewService } ;
7+ use linkerd_stack:: { layer, ExtractParam , NewService } ;
88use std:: {
99 fmt,
1010 future:: Future ,
@@ -27,28 +27,30 @@ pub trait Detect<I>: Clone + Send + Sync + 'static {
2727pub type DetectResult < P > = Result < Option < P > , DetectTimeoutError < P > > ;
2828
2929#[ derive( Error ) ]
30- #[ error( "{} protocol detection timed out after {:?}" , std:: any:: type_name:: <P >( ) , . 0 ) ]
30+ #[ error( "{} protocol detection timed out after {0 :?}" , std:: any:: type_name:: <P >( ) ) ]
3131pub struct DetectTimeoutError < P > ( time:: Duration , std:: marker:: PhantomData < P > ) ;
3232
3333#[ derive( Copy , Clone , Debug ) ]
34- pub struct NewDetectService < D , N > {
34+ pub struct Config < D > {
35+ pub detect : D ,
36+ pub capacity : usize ,
37+ pub timeout : time:: Duration ,
38+ }
39+
40+ #[ derive( Copy , Clone , Debug ) ]
41+ pub struct NewDetectService < P , D , N > {
3542 inner : N ,
36- detect : D ,
37- capacity : usize ,
38- timeout : time:: Duration ,
43+ params : P ,
44+ _detect : std:: marker:: PhantomData < fn ( ) -> D > ,
3945}
4046
4147#[ derive( Copy , Clone , Debug ) ]
4248pub struct DetectService < T , D , N > {
4349 target : T ,
50+ config : Config < D > ,
4451 inner : N ,
45- detect : D ,
46- capacity : usize ,
47- timeout : time:: Duration ,
4852}
4953
50- const BUFFER_CAPACITY : usize = 1024 ;
51-
5254pub fn allow_timeout < P , T > ( ( p, t) : ( DetectResult < P > , T ) ) -> ( Option < P > , T ) {
5355 match p {
5456 Ok ( p) => ( p, t) ,
@@ -59,52 +61,67 @@ pub fn allow_timeout<P, T>((p, t): (DetectResult<P>, T)) -> (Option<P>, T) {
5961 }
6062}
6163
64+ // === impl Config ===
65+
66+ impl < D : Default > Config < D > {
67+ const DEFAULT_CAPACITY : usize = 1024 ;
68+
69+ pub fn from_timeout ( timeout : time:: Duration ) -> Self {
70+ Self {
71+ detect : D :: default ( ) ,
72+ capacity : Self :: DEFAULT_CAPACITY ,
73+ timeout,
74+ }
75+ }
76+ }
77+
6278// === impl NewDetectService ===
6379
64- impl < D : Clone , N > NewDetectService < D , N > {
65- pub fn new ( timeout : time :: Duration , detect : D , inner : N ) -> Self {
80+ impl < P , D , N > NewDetectService < P , D , N > {
81+ pub fn new ( params : P , inner : N ) -> Self {
6682 Self {
67- detect,
6883 inner,
69- timeout ,
70- capacity : BUFFER_CAPACITY ,
84+ params ,
85+ _detect : std :: marker :: PhantomData ,
7186 }
7287 }
7388
74- pub fn layer (
75- timeout : time :: Duration ,
76- detect : D ,
77- ) -> impl layer :: Layer < N , Service = Self > + Clone {
78- layer:: mk ( move |inner| Self :: new ( timeout , detect . clone ( ) , inner) )
89+ pub fn layer ( params : P ) -> impl layer :: Layer < N , Service = Self > + Clone
90+ where
91+ P : Clone ,
92+ {
93+ layer:: mk ( move |inner| Self :: new ( params . clone ( ) , inner) )
7994 }
8095}
8196
82- impl < D : Clone , N : Clone , T > NewService < T > for NewDetectService < D , N > {
97+ impl < T , P , D , N : Clone > NewService < T > for NewDetectService < P , D , N >
98+ where
99+ P : ExtractParam < Config < D > , T > ,
100+ {
83101 type Service = DetectService < T , D , N > ;
84102
85103 fn new_service ( & mut self , target : T ) -> DetectService < T , D , N > {
104+ let config = self . params . extract_param ( & target) ;
86105 DetectService {
87106 target,
88- detect : self . detect . clone ( ) ,
107+ config ,
89108 inner : self . inner . clone ( ) ,
90- capacity : self . capacity ,
91- timeout : self . timeout ,
92109 }
93110 }
94111}
95112
96113// === impl DetectService ===
97114
98- impl < S , T , D , N , I > tower:: Service < I > for DetectService < T , D , N >
115+ impl < I , T , D , N , NSvc > tower:: Service < I > for DetectService < T , D , N >
99116where
100117 T : Clone + Send + ' static ,
101118 I : Send + ' static ,
102119 D : Detect < I > ,
103120 D :: Protocol : std:: fmt:: Debug ,
104- N : NewService < ( DetectResult < D :: Protocol > , T ) , Service = S > + Clone + Send + ' static ,
105- S : tower:: Service < io:: PrefixedIo < I > , Response = ( ) > + Send ,
106- S :: Error : Into < Error > ,
107- S :: Future : Send ,
121+ N : NewService < ( DetectResult < D :: Protocol > , T ) , Service = NSvc > + Clone + Send + ' static ,
122+ NSvc : tower:: Service < io:: PrefixedIo < I > , Response = ( ) > + Send ,
123+ NSvc :: Error : Into < Error > ,
124+ NSvc :: Future : Send ,
108125{
109126 type Response = ( ) ;
110127 type Error = Error ;
@@ -116,15 +133,18 @@ where
116133 }
117134
118135 fn call ( & mut self , mut io : I ) -> Self :: Future {
119- let mut inner = self . inner . clone ( ) ;
120- let mut buf = BytesMut :: with_capacity ( self . capacity ) ;
121- let detect = self . detect . clone ( ) ;
136+ let Config {
137+ detect,
138+ capacity,
139+ timeout,
140+ } = self . config . clone ( ) ;
122141 let target = self . target . clone ( ) ;
123- let timeout = self . timeout ;
142+ let mut inner = self . inner . clone ( ) ;
124143 Box :: pin ( async move {
125- trace ! ( "Starting protocol detection" ) ;
144+ trace ! ( %capacity , ?timeout , "Starting protocol detection" ) ;
126145 let t0 = time:: Instant :: now ( ) ;
127146
147+ let mut buf = BytesMut :: with_capacity ( capacity) ;
128148 let detected = match time:: timeout ( timeout, detect. detect ( & mut io, & mut buf) ) . await {
129149 Ok ( Ok ( protocol) ) => {
130150 debug ! ( ?protocol, elapsed = ?t0. elapsed( ) , "DetectResult" ) ;
0 commit comments