7
7
// modified, or distributed except according to those terms.
8
8
9
9
use futures_util:: FutureExt ;
10
- use keyed_priority_queue:: KeyedPriorityQueue ;
11
10
use tokio:: sync:: mpsc;
12
11
13
12
use std:: {
14
- borrow:: Borrow ,
15
- cmp:: Reverse ,
16
13
collections:: VecDeque ,
17
- hash:: { Hash , Hasher } ,
18
14
str:: FromStr ,
19
15
sync:: { atomic, Arc , Mutex } ,
20
- task:: { Context , Poll , Waker } ,
16
+ task:: { Context , Poll } ,
21
17
time:: { Duration , Instant } ,
22
18
} ;
23
19
@@ -29,12 +25,14 @@ use crate::{
29
25
} ;
30
26
31
27
pub use metrics:: Metrics ;
28
+ use waitlist:: { QueueId , Waitlist } ;
32
29
33
30
mod recycler;
34
31
// this is a really unfortunate name for a module
35
32
pub mod futures;
36
33
mod metrics;
37
34
mod ttl_check_inerval;
35
+ mod waitlist;
38
36
39
37
/// Connection that is idling in the pool.
40
38
#[ derive( Debug ) ]
@@ -104,86 +102,6 @@ impl Exchange {
104
102
}
105
103
}
106
104
107
- #[ derive( Default , Debug ) ]
108
- struct Waitlist {
109
- queue : KeyedPriorityQueue < QueuedWaker , QueueId > ,
110
- }
111
-
112
- impl Waitlist {
113
- /// Returns `true` if pushed.
114
- fn push ( & mut self , waker : Waker , queue_id : QueueId ) -> bool {
115
- // The documentation of Future::poll says:
116
- // Note that on multiple calls to poll, only the Waker from
117
- // the Context passed to the most recent call should be
118
- // scheduled to receive a wakeup.
119
- //
120
- // But the the documentation of KeyedPriorityQueue::push says:
121
- // Adds new element to queue if missing key or replace its
122
- // priority if key exists. In second case doesn’t replace key.
123
- //
124
- // This means we have to remove first to have the most recent
125
- // waker in the queue.
126
- let occupied = self . remove ( queue_id) ;
127
- self . queue . push ( QueuedWaker { queue_id, waker } , queue_id) ;
128
- !occupied
129
- }
130
-
131
- fn pop ( & mut self ) -> Option < Waker > {
132
- match self . queue . pop ( ) {
133
- Some ( ( qw, _) ) => Some ( qw. waker ) ,
134
- None => None ,
135
- }
136
- }
137
-
138
- /// Returns `true` if removed.
139
- fn remove ( & mut self , id : QueueId ) -> bool {
140
- self . queue . remove ( & id) . is_some ( )
141
- }
142
-
143
- fn peek_id ( & mut self ) -> Option < QueueId > {
144
- self . queue . peek ( ) . map ( |( qw, _) | qw. queue_id )
145
- }
146
- }
147
-
148
- const QUEUE_END_ID : QueueId = QueueId ( Reverse ( u64:: MAX ) ) ;
149
-
150
- #[ derive( Debug , Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
151
- pub ( crate ) struct QueueId ( Reverse < u64 > ) ;
152
-
153
- impl QueueId {
154
- fn next ( ) -> Self {
155
- static NEXT_QUEUE_ID : atomic:: AtomicU64 = atomic:: AtomicU64 :: new ( 0 ) ;
156
- let id = NEXT_QUEUE_ID . fetch_add ( 1 , atomic:: Ordering :: SeqCst ) ;
157
- QueueId ( Reverse ( id) )
158
- }
159
- }
160
-
161
- #[ derive( Debug ) ]
162
- struct QueuedWaker {
163
- queue_id : QueueId ,
164
- waker : Waker ,
165
- }
166
-
167
- impl Eq for QueuedWaker { }
168
-
169
- impl Borrow < QueueId > for QueuedWaker {
170
- fn borrow ( & self ) -> & QueueId {
171
- & self . queue_id
172
- }
173
- }
174
-
175
- impl PartialEq for QueuedWaker {
176
- fn eq ( & self , other : & Self ) -> bool {
177
- self . queue_id == other. queue_id
178
- }
179
- }
180
-
181
- impl Hash for QueuedWaker {
182
- fn hash < H : Hasher > ( & self , state : & mut H ) {
183
- self . queue_id . hash ( state)
184
- }
185
- }
186
-
187
105
/// Connection pool data.
188
106
#[ derive( Debug ) ]
189
107
pub struct Inner {
@@ -474,20 +392,16 @@ mod test {
474
392
use waker_fn:: waker_fn;
475
393
476
394
use std:: {
477
- cmp:: Reverse ,
478
395
future:: Future ,
479
396
pin:: pin,
480
397
sync:: { Arc , OnceLock } ,
481
- task:: { Context , Poll , RawWaker , RawWakerVTable , Waker } ,
398
+ task:: { Context , Poll } ,
482
399
time:: Duration ,
483
400
} ;
484
401
485
402
use crate :: {
486
- conn:: pool:: { Pool , QueueId , Waitlist , QUEUE_END_ID } ,
487
- opts:: PoolOpts ,
488
- prelude:: * ,
489
- test_misc:: get_opts,
490
- PoolConstraints , Row , TxOpts , Value ,
403
+ conn:: pool:: Pool , opts:: PoolOpts , prelude:: * , test_misc:: get_opts, PoolConstraints , Row ,
404
+ TxOpts , Value ,
491
405
} ;
492
406
493
407
macro_rules! conn_ex_field {
@@ -1016,7 +930,7 @@ mod test {
1016
930
}
1017
931
drop ( only_conn) ;
1018
932
1019
- assert_eq ! ( 0 , pool. inner. exchange. lock( ) . unwrap( ) . waiting. queue . len( ) ) ;
933
+ assert_eq ! ( 0 , pool. inner. exchange. lock( ) . unwrap( ) . waiting. len( ) ) ;
1020
934
// metrics should catch up with waiting queue (see #335)
1021
935
assert_eq ! (
1022
936
0 ,
@@ -1070,40 +984,6 @@ mod test {
1070
984
Ok ( ( ) )
1071
985
}
1072
986
1073
- #[ test]
1074
- fn waitlist_integrity ( ) {
1075
- const DATA : * const ( ) = & ( ) ;
1076
- const NOOP_CLONE_FN : unsafe fn ( * const ( ) ) -> RawWaker = |_| RawWaker :: new ( DATA , & RW_VTABLE ) ;
1077
- const NOOP_FN : unsafe fn ( * const ( ) ) = |_| { } ;
1078
- static RW_VTABLE : RawWakerVTable =
1079
- RawWakerVTable :: new ( NOOP_CLONE_FN , NOOP_FN , NOOP_FN , NOOP_FN ) ;
1080
- let w = unsafe { Waker :: from_raw ( RawWaker :: new ( DATA , & RW_VTABLE ) ) } ;
1081
-
1082
- let mut waitlist = Waitlist :: default ( ) ;
1083
- assert_eq ! ( 0 , waitlist. queue. len( ) ) ;
1084
-
1085
- waitlist. push ( w. clone ( ) , QueueId ( Reverse ( 4 ) ) ) ;
1086
- waitlist. push ( w. clone ( ) , QueueId ( Reverse ( 2 ) ) ) ;
1087
- waitlist. push ( w. clone ( ) , QueueId ( Reverse ( 8 ) ) ) ;
1088
- waitlist. push ( w. clone ( ) , QUEUE_END_ID ) ;
1089
- waitlist. push ( w. clone ( ) , QueueId ( Reverse ( 10 ) ) ) ;
1090
-
1091
- waitlist. remove ( QueueId ( Reverse ( 8 ) ) ) ;
1092
-
1093
- assert_eq ! ( 4 , waitlist. queue. len( ) ) ;
1094
-
1095
- let ( _, id) = waitlist. queue . pop ( ) . unwrap ( ) ;
1096
- assert_eq ! ( 2 , id. 0 . 0 ) ;
1097
- let ( _, id) = waitlist. queue . pop ( ) . unwrap ( ) ;
1098
- assert_eq ! ( 4 , id. 0 . 0 ) ;
1099
- let ( _, id) = waitlist. queue . pop ( ) . unwrap ( ) ;
1100
- assert_eq ! ( 10 , id. 0 . 0 ) ;
1101
- let ( _, id) = waitlist. queue . pop ( ) . unwrap ( ) ;
1102
- assert_eq ! ( QUEUE_END_ID , id) ;
1103
-
1104
- assert_eq ! ( 0 , waitlist. queue. len( ) ) ;
1105
- }
1106
-
1107
987
#[ tokio:: test]
1108
988
async fn check_absolute_connection_ttl ( ) -> super :: Result < ( ) > {
1109
989
let constraints = PoolConstraints :: new ( 1 , 3 ) . unwrap ( ) ;
@@ -1185,7 +1065,7 @@ mod test {
1185
1065
1186
1066
let queue_len = || {
1187
1067
let exchange = pool. inner . exchange . lock ( ) . unwrap ( ) ;
1188
- exchange. waiting . queue . len ( )
1068
+ exchange. waiting . len ( )
1189
1069
} ;
1190
1070
1191
1071
// Get a connection, so we know the next futures will be
0 commit comments