1
1
use std:: error:: Error as StdError ;
2
2
use std:: marker:: Unpin ;
3
+ use std:: sync:: { Arc , Mutex } ;
3
4
#[ cfg( feature = "runtime" ) ]
4
5
use std:: time:: Duration ;
5
6
@@ -24,7 +25,7 @@ use crate::service::HttpService;
24
25
25
26
use crate :: upgrade:: { OnUpgrade , Pending , Upgraded } ;
26
27
use crate :: { Body , Response } ;
27
-
28
+ use tokio :: time :: Sleep ;
28
29
// Our defaults are chosen for the "majority" case, which usually are not
29
30
// resource constrained, and so the spec default of 64kb can be too limiting
30
31
// for performance.
@@ -100,6 +101,7 @@ where
100
101
ping : Option < ( ping:: Recorder , ping:: Ponger ) > ,
101
102
conn : Connection < T , SendBuf < B :: Data > > ,
102
103
closing : Option < crate :: Error > ,
104
+ idle_timeot : Arc < Mutex < Pin < Box < Sleep > > > >
103
105
}
104
106
105
107
impl < T , S , B , E > Server < T , S , B , E >
@@ -202,6 +204,9 @@ where
202
204
ping,
203
205
conn,
204
206
closing : None ,
207
+ idle_timeot : Arc :: new ( Mutex :: new ( Box :: pin (
208
+ tokio:: time:: sleep ( Duration :: from_secs ( 10 )
209
+ ) ) ) )
205
210
} )
206
211
}
207
212
State :: Serving ( ref mut srv) => {
@@ -224,6 +229,16 @@ where
224
229
T : AsyncRead + AsyncWrite + Unpin ,
225
230
B : HttpBody + ' static ,
226
231
{
232
+
233
+ fn reset_idle ( & self , time : Duration ) {
234
+ let mut sleep = self . idle_timeot . lock ( ) . unwrap ( ) ;
235
+ sleep. as_mut ( ) . reset ( tokio:: time:: Instant :: now ( ) + time) ;
236
+ }
237
+ fn poll_idle ( & self , cx : & mut task:: Context < ' _ > ) -> bool {
238
+ let mut sleep = self . idle_timeot . lock ( ) . unwrap ( ) ;
239
+ sleep. as_mut ( ) . poll ( cx) . is_ready ( )
240
+ }
241
+
227
242
fn poll_server < S , E > (
228
243
& mut self ,
229
244
cx : & mut task:: Context < ' _ > ,
@@ -269,10 +284,16 @@ where
269
284
break ;
270
285
}
271
286
}
272
-
287
+ if self . poll_idle ( cx) {
288
+ log:: info!( "incoming connection complete11" ) ;
289
+ self . conn . graceful_shutdown ( ) ;
290
+ log:: info!( "incoming connection complete" ) ;
291
+ return Poll :: Ready ( Ok ( ( ) ) ) ;
292
+ }
273
293
// When the service is ready, accepts an incoming request.
274
294
match ready ! ( self . conn. poll_accept( cx) ) {
275
295
Some ( Ok ( ( req, mut respond) ) ) => {
296
+ self . reset_idle ( Duration :: from_secs ( 60 * 60 * 24 ) ) ;
276
297
trace ! ( "incoming request" ) ;
277
298
let content_length = headers:: content_length_parse_all ( req. headers ( ) ) ;
278
299
let ping = self
@@ -316,8 +337,9 @@ where
316
337
if let Some ( protocol) = req. extensions_mut ( ) . remove :: < h2:: ext:: Protocol > ( ) {
317
338
req. extensions_mut ( ) . insert ( Protocol :: from_inner ( protocol) ) ;
318
339
}
319
-
320
- let fut = H2Stream :: new ( service. call ( req) , connect_parts, respond) ;
340
+ log:: info!( "{:?}" , respond. stream_id( ) ) ;
341
+ let fut = H2Stream :: new ( service. call ( req) , connect_parts, respond,
342
+ self . idle_timeot . clone ( ) ) ;
321
343
exec. execute_h2stream ( fut) ;
322
344
}
323
345
Some ( Err ( e) ) => {
@@ -373,6 +395,7 @@ pin_project! {
373
395
reply: SendResponse <SendBuf <B :: Data >>,
374
396
#[ pin]
375
397
state: H2StreamState <F , B >,
398
+ idle_timeot: Arc <Mutex <Pin <Box <Sleep >>>>,
376
399
}
377
400
}
378
401
@@ -408,10 +431,12 @@ where
408
431
fut : F ,
409
432
connect_parts : Option < ConnectParts > ,
410
433
respond : SendResponse < SendBuf < B :: Data > > ,
434
+ idle_timeot : Arc < Mutex < Pin < Box < Sleep > > > >
411
435
) -> H2Stream < F , B > {
412
436
H2Stream {
413
437
reply : respond,
414
438
state : H2StreamState :: Service { fut, connect_parts } ,
439
+ idle_timeot
415
440
}
416
441
}
417
442
}
@@ -534,7 +559,12 @@ where
534
559
type Output = ( ) ;
535
560
536
561
fn poll ( self : Pin < & mut Self > , cx : & mut task:: Context < ' _ > ) -> Poll < Self :: Output > {
537
- self . poll2 ( cx) . map ( |res| {
562
+ let idle_timeot = self . idle_timeot . clone ( ) ;
563
+ let poll = self . poll2 ( cx) ;
564
+ poll. map ( |res| {
565
+ log:: info!( "con is idle" ) ;
566
+ let mut sleep = idle_timeot. lock ( ) . unwrap ( ) ;
567
+ sleep. as_mut ( ) . reset ( tokio:: time:: Instant :: now ( ) + Duration :: from_secs ( 10 ) ) ;
538
568
if let Err ( e) = res {
539
569
debug ! ( "stream error: {}" , e) ;
540
570
}
0 commit comments