1
1
use crate :: conntrack:: { Conn , ConnId } ;
2
2
use crate :: subscription:: { Subscription , Trackable } ;
3
3
4
- use crossbeam_channel:: { tick, Receiver } ;
5
4
use hashlink:: linked_hash_map:: LinkedHashMap ;
6
5
use hashlink:: linked_hash_map:: RawEntryMut ;
7
6
use std:: collections:: VecDeque ;
8
7
use std:: time:: { Duration , Instant } ;
9
8
10
9
/// Tracks inactive connection expiration.
11
10
pub ( super ) struct TimerWheel {
12
- /// Period to check for inactive connections (in milliseconds) .
13
- period : usize ,
11
+ /// Period to check for inactive connections.
12
+ period : Duration ,
14
13
/// Start time of the `TimerWheel`.
15
14
start_ts : Instant ,
16
- /// Timeout ticker, fires every `period` milliseconds .
17
- ticker : Receiver < Instant > ,
15
+ /// Previous check time of the `TimerWheel` .
16
+ prev_ts : Instant ,
18
17
/// Index of the next bucket to expire.
19
18
next_bucket : usize ,
20
19
/// List of timers.
@@ -29,11 +28,11 @@ impl TimerWheel {
29
28
panic ! ( "Timeout check period must be smaller than maximum inactivity timeout" )
30
29
}
31
30
let start_ts = Instant :: now ( ) ;
32
- let ticker = tick ( Duration :: from_millis ( timeout_resolution as u64 ) ) ;
31
+ let period = Duration :: from_millis ( timeout_resolution as u64 ) ;
33
32
TimerWheel {
34
- period : timeout_resolution ,
33
+ period,
35
34
start_ts,
36
- ticker ,
35
+ prev_ts : start_ts ,
37
36
next_bucket : 0 ,
38
37
timers : vec ! [ VecDeque :: new( ) ; max_timeout / timeout_resolution] ,
39
38
}
@@ -48,7 +47,8 @@ impl TimerWheel {
48
47
inactivity_window : usize ,
49
48
) {
50
49
let current_time = ( last_seen_ts - self . start_ts ) . as_millis ( ) as usize ;
51
- let timer_index = ( ( current_time + inactivity_window) / self . period ) % self . timers . len ( ) ;
50
+ let period = self . period . as_millis ( ) as usize ;
51
+ let timer_index = ( ( current_time + inactivity_window) / period) % self . timers . len ( ) ;
52
52
log:: debug!( "Inserting into index: {}, {:?}" , timer_index, current_time) ;
53
53
self . timers [ timer_index] . push_back ( conn_id. to_owned ( ) ) ;
54
54
}
@@ -59,9 +59,11 @@ impl TimerWheel {
59
59
& mut self ,
60
60
table : & mut LinkedHashMap < ConnId , Conn < T > > ,
61
61
subscription : & Subscription < T :: Subscribed > ,
62
+ now : Instant ,
62
63
) {
63
64
let table_len = table. len ( ) ;
64
- if let Ok ( now) = self . ticker . try_recv ( ) {
65
+ if now - self . prev_ts >= self . period {
66
+ self . prev_ts = now;
65
67
let nb_removed = self . remove_inactive ( now, table, subscription) ;
66
68
log:: debug!(
67
69
"expired: {} ({})" ,
@@ -83,7 +85,7 @@ impl TimerWheel {
83
85
table : & mut LinkedHashMap < ConnId , Conn < T > > ,
84
86
subscription : & Subscription < T :: Subscribed > ,
85
87
) -> usize {
86
- let period = self . period ;
88
+ let period = self . period . as_millis ( ) as usize ;
87
89
let nb_buckets = self . timers . len ( ) ;
88
90
let mut not_expired: Vec < ( usize , ConnId ) > = vec ! [ ] ;
89
91
let check_time = ( now - self . start_ts ) . as_millis ( ) as usize / period * period;
0 commit comments