@@ -16,10 +16,9 @@ use std::net::SocketAddr;
16
16
use std:: rc:: { Rc , Weak } ;
17
17
use std:: time:: Duration ;
18
18
19
- use futures:: future;
20
19
use futures:: task:: { self , Task } ;
20
+ use futures:: future:: { self , Select , Map } ;
21
21
use futures:: { Future , Stream , Poll , Async , Sink , StartSend , AsyncSink } ;
22
- use futures:: future:: Map ;
23
22
24
23
#[ cfg( feature = "compat" ) ]
25
24
use http;
@@ -88,6 +87,17 @@ where B: Stream<Error=::Error>,
88
87
shutdown_timeout : Duration ,
89
88
}
90
89
90
+ /// The Future of an Server.
91
+ pub struct ServerFuture < F , S , B >
92
+ where B : Stream < Error =:: Error > ,
93
+ B :: Item : AsRef < [ u8 ] > ,
94
+ {
95
+ server : Server < S , B > ,
96
+ info : Rc < RefCell < Info > > ,
97
+ shutdown_signal : F ,
98
+ shutdown : Option < Select < WaitUntilZero , Timeout > > ,
99
+ }
100
+
91
101
impl < B : AsRef < [ u8 ] > + ' static > Http < B > {
92
102
/// Creates a new instance of the HTTP protocol, ready to spawn a server or
93
103
/// start accepting connections.
@@ -464,6 +474,21 @@ impl<S, B> Server<S, B>
464
474
self
465
475
}
466
476
477
+ /// Configure the `shutdown_signal`.
478
+ pub fn shutdown_signal < F > ( self , signal : F ) -> ServerFuture < F , S , B >
479
+ where F : Future < Item = ( ) , Error = ( ) >
480
+ {
481
+ ServerFuture {
482
+ server : self ,
483
+ info : Rc :: new ( RefCell :: new ( Info {
484
+ active : 0 ,
485
+ blocker : None ,
486
+ } ) ) ,
487
+ shutdown_signal : signal,
488
+ shutdown : None ,
489
+ }
490
+ }
491
+
467
492
/// Execute this server infinitely.
468
493
///
469
494
/// This method does not currently return, but it will return an error if
@@ -578,19 +603,85 @@ impl<S, B> Future for Server<S, B>
578
603
}
579
604
}
580
605
606
+ impl < F , S , B > Future for ServerFuture < F , S , B >
607
+ where F : Future < Item = ( ) , Error = ( ) > ,
608
+ S : NewService < Request = Request , Response = Response < B > , Error = :: Error > + ' static ,
609
+ B : Stream < Error =:: Error > + ' static ,
610
+ B :: Item : AsRef < [ u8 ] > ,
611
+ {
612
+ type Item = ( ) ;
613
+ type Error = ( ) ;
614
+
615
+ fn poll ( & mut self ) -> Poll < Self :: Item , Self :: Error > {
616
+ loop {
617
+ if let Some ( ref mut shutdown) = self . shutdown {
618
+ match shutdown. poll ( ) {
619
+ Ok ( Async :: Ready ( _) ) => return Ok ( Async :: Ready ( ( ) ) ) ,
620
+ Ok ( Async :: NotReady ) => return Ok ( Async :: NotReady ) ,
621
+ Err ( ( e, _) ) => debug ! ( "internal error: {:?}" , e) ,
622
+ }
623
+ } else if let Ok ( Async :: Ready ( ( ) ) ) = self . shutdown_signal . poll ( ) {
624
+ match Timeout :: new ( self . server . shutdown_timeout , & self . server . handle ( ) ) {
625
+ Ok ( timeout) => {
626
+ let wait = WaitUntilZero { info : self . info . clone ( ) } ;
627
+ self . shutdown = Some ( wait. select ( timeout) )
628
+ } ,
629
+ Err ( e) => debug ! ( "internal error: {:?}" , e) ,
630
+ }
631
+ } else {
632
+ match self . server . listener . accept ( ) {
633
+ Ok ( ( socket, addr) ) => {
634
+ match self . server . new_service . new_service ( ) {
635
+ Ok ( inner_srv) => {
636
+ let srv = NotifyService {
637
+ inner : inner_srv,
638
+ info : Rc :: downgrade ( & self . info ) ,
639
+ } ;
640
+ self . info . borrow_mut ( ) . active += 1 ;
641
+ self . server . protocol . bind_connection ( & self . server . handle ( ) ,
642
+ socket,
643
+ addr,
644
+ srv)
645
+ } ,
646
+ Err ( e) => debug ! ( "internal error: {:?}" , e) ,
647
+ }
648
+ } ,
649
+ Err ( ref e) if e. kind ( ) == io:: ErrorKind :: WouldBlock => return Ok ( Async :: NotReady ) ,
650
+ Err ( e) => debug ! ( "internal error: {:?}" , e) ,
651
+ }
652
+ }
653
+ }
654
+ }
655
+ }
656
+
657
+
581
658
impl < S : fmt:: Debug , B : Stream < Error =:: Error > > fmt:: Debug for Server < S , B >
582
659
where B :: Item : AsRef < [ u8 ] >
583
660
{
584
661
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
585
662
f. debug_struct ( "Server" )
586
- . field ( "core " , & "..." )
663
+ . field ( "reactor " , & "..." )
587
664
. field ( "listener" , & self . listener )
588
665
. field ( "new_service" , & self . new_service )
589
666
. field ( "protocol" , & self . protocol )
590
667
. finish ( )
591
668
}
592
669
}
593
670
671
+ impl < F , S : fmt:: Debug , B : Stream < Error =:: Error > > fmt:: Debug for ServerFuture < F , S , B >
672
+ where B :: Item : AsRef < [ u8 ] > ,
673
+ F : Future < Item = ( ) , Error = ( ) >
674
+ {
675
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
676
+ f. debug_struct ( "ServerFuture" )
677
+ . field ( "server" , & self . server )
678
+ . field ( "info" , & "..." )
679
+ . field ( "shutdown_signal" , & "..." )
680
+ . field ( "shutdown" , & "..." )
681
+ . finish ( )
682
+ }
683
+ }
684
+
594
685
struct NotifyService < S > {
595
686
inner : S ,
596
687
info : Weak < RefCell < Info > > ,
0 commit comments