@@ -30,7 +30,6 @@ mod response;
30
30
31
31
/// A Client to make outgoing HTTP requests.
32
32
pub struct Client < H > {
33
- //handle: Option<thread::JoinHandle<()>>,
34
33
tx : http:: channel:: Sender < Notify < H > > ,
35
34
}
36
35
@@ -64,16 +63,6 @@ impl<H> Client<H> {
64
63
pub fn configure ( ) -> Config < DefaultConnector > {
65
64
Config :: default ( )
66
65
}
67
-
68
- /*TODO
69
- pub fn http() -> Config<HttpConnector> {
70
-
71
- }
72
-
73
- pub fn https() -> Config<HttpsConnector> {
74
-
75
- }
76
- */
77
66
}
78
67
79
68
impl < H : Handler < <DefaultConnector as Connect >:: Output > > Client < H > {
@@ -243,14 +232,6 @@ impl<H> fmt::Display for ClientError<H> {
243
232
}
244
233
}
245
234
246
- /*
247
- impl Drop for Client {
248
- fn drop(&mut self) {
249
- self.handle.take().map(|handle| handle.join());
250
- }
251
- }
252
- */
253
-
254
235
/// A trait to react to client events that happen for each message.
255
236
///
256
237
/// Each event handler returns it's desired `Next` action.
@@ -338,15 +319,16 @@ struct Context<K, H> {
338
319
}
339
320
340
321
impl < K : http:: Key , H > Context < K , H > {
341
- fn pop_queue ( & mut self , key : & K ) -> Queued < H > {
322
+ fn pop_queue ( & mut self , key : & K ) -> Option < Queued < H > > {
342
323
let mut should_remove = false ;
343
324
let queued = {
344
- let mut vec = self . queue . get_mut ( key) . expect ( "handler not in queue for key" ) ;
345
- let queued = vec. remove ( 0 ) ;
346
- if vec. is_empty ( ) {
347
- should_remove = true ;
348
- }
349
- queued
325
+ self . queue . get_mut ( key) . map ( |vec| {
326
+ let queued = vec. remove ( 0 ) ;
327
+ if vec. is_empty ( ) {
328
+ should_remove = true ;
329
+ }
330
+ queued
331
+ } )
350
332
} ;
351
333
if should_remove {
352
334
self . queue . remove ( key) ;
@@ -379,16 +361,22 @@ impl<K: http::Key, H> Context<K, H> {
379
361
impl < K : http:: Key , H : Handler < T > , T : Transport > http:: MessageHandlerFactory < K , T > for Context < K , H > {
380
362
type Output = Message < H , T > ;
381
363
382
- fn create ( & mut self , seed : http:: Seed < K > ) -> Self :: Output {
364
+ fn create ( & mut self , seed : http:: Seed < K > ) -> Option < Self :: Output > {
383
365
let key = seed. key ( ) ;
384
- let queued = self . pop_queue ( key) ;
385
- let ( url, mut handler) = ( queued. url , queued. handler ) ;
386
- handler. on_control ( seed. control ( ) ) ;
387
- Message {
388
- handler : handler,
389
- url : Some ( url) ,
390
- _marker : PhantomData ,
391
- }
366
+ self . pop_queue ( key) . map ( |queued| {
367
+ let ( url, mut handler) = ( queued. url , queued. handler ) ;
368
+ handler. on_control ( seed. control ( ) ) ;
369
+
370
+ Message {
371
+ handler : handler,
372
+ url : Some ( url) ,
373
+ _marker : PhantomData ,
374
+ }
375
+ } )
376
+ }
377
+
378
+ fn keep_alive_interest ( & self ) -> Next {
379
+ Next :: wait ( )
392
380
}
393
381
}
394
382
@@ -402,6 +390,7 @@ where C: Connect,
402
390
C :: Output : Transport ,
403
391
H : Handler < C :: Output > {
404
392
Connector ( C , http:: channel:: Receiver < Notify < H > > ) ,
393
+ Connecting ( ( C :: Key , C :: Output ) ) ,
405
394
Socket ( http:: Conn < C :: Key , C :: Output , Message < H , C :: Output > > )
406
395
}
407
396
@@ -415,31 +404,55 @@ where
415
404
416
405
impl < C , H > rotor:: Machine for ClientFsm < C , H >
417
406
where C : Connect ,
407
+ C :: Key : fmt:: Debug ,
418
408
C :: Output : Transport ,
419
409
H : Handler < C :: Output > {
420
410
type Context = Context < C :: Key , H > ;
421
411
type Seed = ( C :: Key , C :: Output ) ;
422
412
423
413
fn create ( seed : Self :: Seed , scope : & mut Scope < Self :: Context > ) -> rotor:: Response < Self , rotor:: Void > {
424
414
rotor_try ! ( scope. register( & seed. 1 , EventSet :: writable( ) , PollOpt :: level( ) ) ) ;
425
- rotor:: Response :: ok (
426
- ClientFsm :: Socket (
427
- http:: Conn :: new ( seed. 0 , seed. 1 , scope. notifier ( ) )
428
- . keep_alive ( scope. keep_alive )
429
- )
430
- )
415
+ rotor:: Response :: ok ( ClientFsm :: Connecting ( seed) )
431
416
}
432
417
433
418
fn ready ( self , events : EventSet , scope : & mut Scope < Self :: Context > ) -> rotor:: Response < Self , Self :: Seed > {
434
419
match self {
435
- ClientFsm :: Connector ( ..) => {
436
- unreachable ! ( "Connector can never be ready" )
437
- } ,
438
420
ClientFsm :: Socket ( conn) => {
439
421
let res = conn. ready ( events, scope) ;
440
422
let now = scope. now ( ) ;
441
423
scope. conn_response ( res, now)
424
+ } ,
425
+ ClientFsm :: Connecting ( mut seed) => {
426
+ if events. is_error ( ) || events. is_hup ( ) {
427
+ if let Some ( err) = seed. 1 . take_socket_error ( ) . err ( ) {
428
+ debug ! ( "error while connecting: {:?}" , err) ;
429
+ scope. pop_queue ( & seed. 0 ) . map ( move |mut queued| queued. handler . on_error ( :: Error :: Io ( err) ) ) ;
430
+ rotor:: Response :: done ( )
431
+ } else {
432
+ trace ! ( "connecting is_error, but no socket error" ) ;
433
+ rotor:: Response :: ok ( ClientFsm :: Connecting ( seed) )
434
+ }
435
+ } else if events. is_writable ( ) {
436
+ if scope. queue . contains_key ( & seed. 0 ) {
437
+ trace ! ( "connected and writable {:?}" , seed. 0 ) ;
438
+ rotor:: Response :: ok (
439
+ ClientFsm :: Socket (
440
+ http:: Conn :: new ( seed. 0 , seed. 1 , Next :: write ( ) . timeout ( scope. connect_timeout ) , scope. notifier ( ) )
441
+ . keep_alive ( scope. keep_alive )
442
+ )
443
+ )
444
+ } else {
445
+ trace ! ( "connected, but queued handler is gone: {:?}" , seed. 0 ) ; // probably took too long connecting
446
+ rotor:: Response :: done ( )
447
+ }
448
+ } else {
449
+ // spurious?
450
+ rotor:: Response :: ok ( ClientFsm :: Connecting ( seed) )
451
+ }
442
452
}
453
+ ClientFsm :: Connector ( ..) => {
454
+ unreachable ! ( "Connector can never be ready" )
455
+ } ,
443
456
}
444
457
}
445
458
@@ -477,6 +490,7 @@ where C: Connect,
477
490
None => rotor:: Response :: ok ( self )
478
491
}
479
492
}
493
+ ClientFsm :: Connecting ( ..) => unreachable ! ( ) ,
480
494
ClientFsm :: Socket ( conn) => {
481
495
let res = conn. timeout ( scope) ;
482
496
let now = scope. now ( ) ;
@@ -494,13 +508,15 @@ where C: Connect,
494
508
let res = conn. wakeup ( scope) ;
495
509
let now = scope. now ( ) ;
496
510
scope. conn_response ( res, now)
497
- }
511
+ } ,
512
+ ClientFsm :: Connecting ( ..) => unreachable ! ( "connecting sockets should not be woken up" )
498
513
}
499
514
}
500
515
}
501
516
502
517
impl < C , H > ClientFsm < C , H >
503
518
where C : Connect ,
519
+ C :: Key : fmt:: Debug ,
504
520
C :: Output : Transport ,
505
521
H : Handler < C :: Output > {
506
522
fn connect ( self , scope : & mut rotor:: Scope < <Self as rotor:: Machine >:: Context > ) -> rotor:: Response < Self , <Self as rotor:: Machine >:: Seed > {
@@ -509,13 +525,12 @@ where C: Connect,
509
525
if let Some ( ( key, res) ) = connector. connected ( ) {
510
526
match res {
511
527
Ok ( socket) => {
512
- trace ! ( "connected" ) ;
528
+ trace ! ( "connecting {:?}" , key ) ;
513
529
return rotor:: Response :: spawn ( ClientFsm :: Connector ( connector, rx) , ( key, socket) ) ;
514
530
} ,
515
531
Err ( e) => {
516
- trace ! ( "connected error = {:?}" , e) ;
517
- let mut queued = scope. pop_queue ( & key) ;
518
- let _ = queued. handler . on_error ( :: Error :: Io ( e) ) ;
532
+ trace ! ( "connect error = {:?}" , e) ;
533
+ scope. pop_queue ( & key) . map ( |mut queued| queued. handler . on_error ( :: Error :: Io ( e) ) ) ;
519
534
}
520
535
}
521
536
}
0 commit comments