@@ -725,7 +725,7 @@ mod dispatch_impl {
725725 let handle = core. handle ( ) ;
726726 let closes = Arc :: new ( AtomicUsize :: new ( 0 ) ) ;
727727 let client = Client :: configure ( )
728- . connector ( DebugConnector ( HttpConnector :: new ( 1 , & core. handle ( ) ) , closes. clone ( ) ) )
728+ . connector ( DebugConnector :: with_http_and_closes ( HttpConnector :: new ( 1 , & core. handle ( ) ) , closes. clone ( ) ) )
729729 . build ( & handle) ;
730730
731731 let ( tx1, rx1) = oneshot:: channel ( ) ;
@@ -784,7 +784,7 @@ mod dispatch_impl {
784784
785785 let res = {
786786 let client = Client :: configure ( )
787- . connector ( DebugConnector ( HttpConnector :: new ( 1 , & handle) , closes. clone ( ) ) )
787+ . connector ( DebugConnector :: with_http_and_closes ( HttpConnector :: new ( 1 , & handle) , closes. clone ( ) ) )
788788 . build ( & handle) ;
789789 client. get ( uri) . and_then ( move |res| {
790790 assert_eq ! ( res. status( ) , hyper:: StatusCode :: Ok ) ;
@@ -834,7 +834,7 @@ mod dispatch_impl {
834834 let uri = format ! ( "http://{}/a" , addr) . parse ( ) . unwrap ( ) ;
835835
836836 let client = Client :: configure ( )
837- . connector ( DebugConnector ( HttpConnector :: new ( 1 , & handle) , closes. clone ( ) ) )
837+ . connector ( DebugConnector :: with_http_and_closes ( HttpConnector :: new ( 1 , & handle) , closes. clone ( ) ) )
838838 . build ( & handle) ;
839839 let res = client. get ( uri) . and_then ( move |res| {
840840 assert_eq ! ( res. status( ) , hyper:: StatusCode :: Ok ) ;
@@ -883,7 +883,7 @@ mod dispatch_impl {
883883
884884 let res = {
885885 let client = Client :: configure ( )
886- . connector ( DebugConnector ( HttpConnector :: new ( 1 , & handle) , closes. clone ( ) ) )
886+ . connector ( DebugConnector :: with_http_and_closes ( HttpConnector :: new ( 1 , & handle) , closes. clone ( ) ) )
887887 . build ( & handle) ;
888888 client. get ( uri)
889889 } ;
@@ -927,7 +927,7 @@ mod dispatch_impl {
927927
928928 let res = {
929929 let client = Client :: configure ( )
930- . connector ( DebugConnector ( HttpConnector :: new ( 1 , & handle) , closes. clone ( ) ) )
930+ . connector ( DebugConnector :: with_http_and_closes ( HttpConnector :: new ( 1 , & handle) , closes. clone ( ) ) )
931931 . build ( & handle) ;
932932 // notably, havent read body yet
933933 client. get ( uri)
@@ -966,7 +966,7 @@ mod dispatch_impl {
966966 let uri = format ! ( "http://{}/a" , addr) . parse ( ) . unwrap ( ) ;
967967
968968 let client = Client :: configure ( )
969- . connector ( DebugConnector ( HttpConnector :: new ( 1 , & handle) , closes. clone ( ) ) )
969+ . connector ( DebugConnector :: with_http_and_closes ( HttpConnector :: new ( 1 , & handle) , closes. clone ( ) ) )
970970 . keep_alive ( false )
971971 . build ( & handle) ;
972972 let res = client. get ( uri) . and_then ( move |res| {
@@ -1005,7 +1005,7 @@ mod dispatch_impl {
10051005 let uri = format ! ( "http://{}/a" , addr) . parse ( ) . unwrap ( ) ;
10061006
10071007 let client = Client :: configure ( )
1008- . connector ( DebugConnector ( HttpConnector :: new ( 1 , & handle) , closes. clone ( ) ) )
1008+ . connector ( DebugConnector :: with_http_and_closes ( HttpConnector :: new ( 1 , & handle) , closes. clone ( ) ) )
10091009 . build ( & handle) ;
10101010 let res = client. get ( uri) . and_then ( move |res| {
10111011 assert_eq ! ( res. status( ) , hyper:: StatusCode :: Ok ) ;
@@ -1095,7 +1095,7 @@ mod dispatch_impl {
10951095 let uri = format ! ( "http://{}/a" , addr) . parse ( ) . unwrap ( ) ;
10961096
10971097 let client = Client :: configure ( )
1098- . connector ( DebugConnector ( HttpConnector :: new ( 1 , & handle) , closes. clone ( ) ) )
1098+ . connector ( DebugConnector :: with_http_and_closes ( HttpConnector :: new ( 1 , & handle) , closes. clone ( ) ) )
10991099 . executor ( handle. clone ( ) ) ;
11001100 let res = client. get ( uri) . and_then ( move |res| {
11011101 assert_eq ! ( res. status( ) , hyper:: StatusCode :: Ok ) ;
@@ -1110,7 +1110,79 @@ mod dispatch_impl {
11101110 assert_eq ! ( closes. load( Ordering :: Relaxed ) , 1 ) ;
11111111 }
11121112
1113- struct DebugConnector ( HttpConnector , Arc < AtomicUsize > ) ;
1113+ #[ test]
1114+ fn idle_conn_prevents_connect_call ( ) {
1115+ let _ = pretty_env_logger:: try_init ( ) ;
1116+
1117+ let server = TcpListener :: bind ( "127.0.0.1:0" ) . unwrap ( ) ;
1118+ let addr = server. local_addr ( ) . unwrap ( ) ;
1119+ let mut core = Core :: new ( ) . unwrap ( ) ;
1120+ let handle = core. handle ( ) ;
1121+ let connector = DebugConnector :: new ( & handle) ;
1122+ let connects = connector. connects . clone ( ) ;
1123+
1124+ let ( tx1, rx1) = oneshot:: channel ( ) ;
1125+ let ( tx2, rx2) = oneshot:: channel ( ) ;
1126+
1127+ thread:: spawn ( move || {
1128+ let mut sock = server. accept ( ) . unwrap ( ) . 0 ;
1129+ sock. set_read_timeout ( Some ( Duration :: from_secs ( 5 ) ) ) . unwrap ( ) ;
1130+ sock. set_write_timeout ( Some ( Duration :: from_secs ( 5 ) ) ) . unwrap ( ) ;
1131+ let mut buf = [ 0 ; 4096 ] ;
1132+ sock. read ( & mut buf) . expect ( "read 1" ) ;
1133+ sock. write_all ( b"HTTP/1.1 200 OK\r \n Content-Length: 0\r \n \r \n " ) . unwrap ( ) ;
1134+ let _ = tx1. send ( ( ) ) ;
1135+
1136+ sock. read ( & mut buf) . expect ( "read 2" ) ;
1137+ sock. write_all ( b"HTTP/1.1 200 OK\r \n Content-Length: 0\r \n \r \n " ) . unwrap ( ) ;
1138+ let _ = tx2. send ( ( ) ) ;
1139+ } ) ;
1140+
1141+ let uri: hyper:: Uri = format ! ( "http://{}/a" , addr) . parse ( ) . unwrap ( ) ;
1142+
1143+ let client = Client :: configure ( )
1144+ . connector ( connector)
1145+ . build ( & handle) ;
1146+
1147+ let res = client. get ( uri. clone ( ) ) . and_then ( move |res| {
1148+ assert_eq ! ( res. status( ) , hyper:: StatusCode :: Ok ) ;
1149+ res. body ( ) . concat2 ( )
1150+ } ) ;
1151+ let rx = rx1. map_err ( |_| hyper:: Error :: Io ( io:: Error :: new ( io:: ErrorKind :: Other , "thread panicked" ) ) ) ;
1152+ core. run ( res. join ( rx) . map ( |r| r. 0 ) ) . unwrap ( ) ;
1153+ assert_eq ! ( connects. load( Ordering :: Relaxed ) , 1 ) ;
1154+
1155+ let res2 = client. get ( uri) . and_then ( move |res| {
1156+ assert_eq ! ( res. status( ) , hyper:: StatusCode :: Ok ) ;
1157+ res. body ( ) . concat2 ( )
1158+ } ) ;
1159+ let rx = rx2. map_err ( |_| hyper:: Error :: Io ( io:: Error :: new ( io:: ErrorKind :: Other , "thread panicked" ) ) ) ;
1160+ core. run ( res2. join ( rx) . map ( |r| r. 0 ) ) . unwrap ( ) ;
1161+
1162+ assert_eq ! ( connects. load( Ordering :: Relaxed ) , 1 ) ;
1163+ }
1164+
1165+
1166+ struct DebugConnector {
1167+ http : HttpConnector ,
1168+ closes : Arc < AtomicUsize > ,
1169+ connects : Arc < AtomicUsize > ,
1170+ }
1171+
1172+ impl DebugConnector {
1173+ fn new ( handle : & Handle ) -> DebugConnector {
1174+ let http = HttpConnector :: new ( 1 , handle) ;
1175+ DebugConnector :: with_http_and_closes ( http, Arc :: new ( AtomicUsize :: new ( 0 ) ) )
1176+ }
1177+
1178+ fn with_http_and_closes ( http : HttpConnector , closes : Arc < AtomicUsize > ) -> DebugConnector {
1179+ DebugConnector {
1180+ http : http,
1181+ closes : closes,
1182+ connects : Arc :: new ( AtomicUsize :: new ( 0 ) ) ,
1183+ }
1184+ }
1185+ }
11141186
11151187 impl Service for DebugConnector {
11161188 type Request = Uri ;
@@ -1119,8 +1191,11 @@ mod dispatch_impl {
11191191 type Future = Box < Future < Item = DebugStream , Error = io:: Error > > ;
11201192
11211193 fn call ( & self , uri : Uri ) -> Self :: Future {
1122- let counter = self . 1 . clone ( ) ;
1123- Box :: new ( self . 0 . call ( uri) . map ( move |s| DebugStream ( s, counter) ) )
1194+ self . connects . fetch_add ( 1 , Ordering :: SeqCst ) ;
1195+ let closes = self . closes . clone ( ) ;
1196+ Box :: new ( self . http . call ( uri) . map ( move |s| {
1197+ DebugStream ( s, closes)
1198+ } ) )
11241199 }
11251200 }
11261201
0 commit comments