@@ -281,11 +281,11 @@ where C: Connect + Sync + 'static,
281281 }
282282
283283 fn send_request ( & self , mut req : Request < B > , pool_key : PoolKey ) -> impl Future < Item =Response < Body > , Error =ClientError < B > > {
284- let race = self . pool_checkout_or_connect ( req. uri ( ) . clone ( ) , pool_key) ;
284+ let conn = self . connection_for ( req. uri ( ) . clone ( ) , pool_key) ;
285285
286286 let ver = self . ver ;
287287 let executor = self . executor . clone ( ) ;
288- race . and_then ( move |mut pooled| {
288+ conn . and_then ( move |mut pooled| {
289289 if ver == Ver :: Http1 {
290290 // CONNECT always sends origin-form, so check it first...
291291 if req. method ( ) == & Method :: CONNECT {
@@ -365,9 +365,22 @@ where C: Connect + Sync + 'static,
365365 } )
366366 }
367367
368- fn pool_checkout_or_connect ( & self , uri : Uri , pool_key : PoolKey )
368+ fn connection_for ( & self , uri : Uri , pool_key : PoolKey )
369369 -> impl Future < Item =Pooled < PoolClient < B > > , Error =ClientError < B > >
370370 {
371+ // This actually races 2 different futures to try to get a ready
372+ // connection the fastest, and to reduce connection churn.
373+ //
374+ // - If the pool has an idle connection waiting, that's used
375+ // immediately.
376+ // - Otherwise, the Connector is asked to start connecting to
377+ // the destination Uri.
378+ // - Meanwhile, the pool Checkout is watching to see if any other
379+ // request finishes and tries to insert an idle connection.
380+ // - If a new connection is started, but the Checkout wins after
381+ // (an idle connection becamse available first), the started
382+ // connection future is spawned into the runtime to complete,
383+ // and then be inserted into the pool as an idle connection.
371384 let checkout = self . pool . checkout ( pool_key. clone ( ) ) ;
372385 let connect = self . connect_to ( uri, pool_key) ;
373386
0 commit comments