@@ -95,6 +95,21 @@ impl<T: Send + Sync> ResourcePool<T> {
95
95
Ok ( ( ) )
96
96
}
97
97
98
+ /// Give back a resource pool item to the pool
99
+ /// If the resource pool item has not been taken yet, the resource will be given back
100
+ /// If the resource pool item has been taken, nothing will happen
101
+ pub fn give_back_resource_pool_item (
102
+ & self ,
103
+ resource_pool_item : ResourcePoolItem < ' _ , T > ,
104
+ ) -> StdResult < ( ) > {
105
+ let mut resource_pool_item = resource_pool_item;
106
+ resource_pool_item
107
+ . take ( )
108
+ . map ( |resource_item| self . give_back_resource ( resource_item, self . discriminant ( ) ?) ) ;
109
+
110
+ Ok ( ( ) )
111
+ }
112
+
98
113
/// Clear the pool
99
114
pub fn clear ( & self ) {
100
115
let mut resources = self . resources . lock ( ) . unwrap ( ) ;
@@ -168,7 +183,7 @@ impl<'a, T: Send + Sync> ResourcePoolItem<'a, T> {
168
183
}
169
184
170
185
/// Take the inner resource if exists
171
- pub fn take ( & mut self ) -> Option < T > {
186
+ fn take ( & mut self ) -> Option < T > {
172
187
self . resource . take ( )
173
188
}
174
189
}
@@ -311,4 +326,36 @@ mod tests {
311
326
312
327
assert_eq ! ( pool. count( ) . unwrap( ) , pool_size - 1 ) ;
313
328
}
329
+
330
+ #[ tokio:: test]
331
+ async fn test_resource_pool_gives_back_fresh_resource_pool_item_if_not_taken_yet ( ) {
332
+ let pool_size = 10 ;
333
+ let resources_expected: Vec < String > = ( 0 ..pool_size) . map ( |i| i. to_string ( ) ) . collect ( ) ;
334
+ let pool = ResourcePool :: < String > :: new ( pool_size, resources_expected. clone ( ) ) ;
335
+ assert_eq ! ( pool. count( ) . unwrap( ) , pool_size) ;
336
+
337
+ let resource_item = pool. acquire_resource ( Duration :: from_millis ( 10 ) ) . unwrap ( ) ;
338
+ assert_eq ! ( pool. count( ) . unwrap( ) , pool_size - 1 ) ;
339
+ pool. give_back_resource_pool_item ( resource_item) . unwrap ( ) ;
340
+
341
+ assert_eq ! ( pool. count( ) . unwrap( ) , pool_size) ;
342
+ }
343
+
344
+ #[ tokio:: test]
345
+ async fn test_resource_pool_does_not_give_back_fresh_resource_pool_item_if_already_taken ( ) {
346
+ let pool_size = 10 ;
347
+ let resources_expected: Vec < String > = ( 0 ..pool_size) . map ( |i| i. to_string ( ) ) . collect ( ) ;
348
+ let pool = ResourcePool :: < String > :: new ( pool_size, resources_expected. clone ( ) ) ;
349
+ assert_eq ! ( pool. count( ) . unwrap( ) , pool_size) ;
350
+
351
+ {
352
+ // Resource taken will be dropped when exiting this block scope
353
+ let mut resource_item = pool. acquire_resource ( Duration :: from_millis ( 10 ) ) . unwrap ( ) ;
354
+ assert_eq ! ( pool. count( ) . unwrap( ) , pool_size - 1 ) ;
355
+ let _resource = resource_item. take ( ) . unwrap ( ) ; // This can only happen in this module as 'take' is private
356
+ pool. give_back_resource_pool_item ( resource_item) . unwrap ( ) ;
357
+ }
358
+
359
+ assert_eq ! ( pool. count( ) . unwrap( ) , pool_size - 1 ) ;
360
+ }
314
361
}
0 commit comments