@@ -725,7 +725,7 @@ mod dispatch_impl {
725
725
let handle = core. handle ( ) ;
726
726
let closes = Arc :: new ( AtomicUsize :: new ( 0 ) ) ;
727
727
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 ( ) ) )
729
729
. build ( & handle) ;
730
730
731
731
let ( tx1, rx1) = oneshot:: channel ( ) ;
@@ -784,7 +784,7 @@ mod dispatch_impl {
784
784
785
785
let res = {
786
786
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 ( ) ) )
788
788
. build ( & handle) ;
789
789
client. get ( uri) . and_then ( move |res| {
790
790
assert_eq ! ( res. status( ) , hyper:: StatusCode :: Ok ) ;
@@ -834,7 +834,7 @@ mod dispatch_impl {
834
834
let uri = format ! ( "http://{}/a" , addr) . parse ( ) . unwrap ( ) ;
835
835
836
836
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 ( ) ) )
838
838
. build ( & handle) ;
839
839
let res = client. get ( uri) . and_then ( move |res| {
840
840
assert_eq ! ( res. status( ) , hyper:: StatusCode :: Ok ) ;
@@ -883,7 +883,7 @@ mod dispatch_impl {
883
883
884
884
let res = {
885
885
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 ( ) ) )
887
887
. build ( & handle) ;
888
888
client. get ( uri)
889
889
} ;
@@ -927,7 +927,7 @@ mod dispatch_impl {
927
927
928
928
let res = {
929
929
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 ( ) ) )
931
931
. build ( & handle) ;
932
932
// notably, havent read body yet
933
933
client. get ( uri)
@@ -966,7 +966,7 @@ mod dispatch_impl {
966
966
let uri = format ! ( "http://{}/a" , addr) . parse ( ) . unwrap ( ) ;
967
967
968
968
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 ( ) ) )
970
970
. keep_alive ( false )
971
971
. build ( & handle) ;
972
972
let res = client. get ( uri) . and_then ( move |res| {
@@ -1005,7 +1005,7 @@ mod dispatch_impl {
1005
1005
let uri = format ! ( "http://{}/a" , addr) . parse ( ) . unwrap ( ) ;
1006
1006
1007
1007
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 ( ) ) )
1009
1009
. build ( & handle) ;
1010
1010
let res = client. get ( uri) . and_then ( move |res| {
1011
1011
assert_eq ! ( res. status( ) , hyper:: StatusCode :: Ok ) ;
@@ -1095,7 +1095,7 @@ mod dispatch_impl {
1095
1095
let uri = format ! ( "http://{}/a" , addr) . parse ( ) . unwrap ( ) ;
1096
1096
1097
1097
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 ( ) ) )
1099
1099
. executor ( handle. clone ( ) ) ;
1100
1100
let res = client. get ( uri) . and_then ( move |res| {
1101
1101
assert_eq ! ( res. status( ) , hyper:: StatusCode :: Ok ) ;
@@ -1110,7 +1110,79 @@ mod dispatch_impl {
1110
1110
assert_eq ! ( closes. load( Ordering :: Relaxed ) , 1 ) ;
1111
1111
}
1112
1112
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
+ }
1114
1186
1115
1187
impl Service for DebugConnector {
1116
1188
type Request = Uri ;
@@ -1119,8 +1191,11 @@ mod dispatch_impl {
1119
1191
type Future = Box < Future < Item = DebugStream , Error = io:: Error > > ;
1120
1192
1121
1193
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
+ } ) )
1124
1199
}
1125
1200
}
1126
1201
0 commit comments