@@ -402,7 +402,7 @@ pub mod tests_postgres {
402
402
pub mod redis_pool {
403
403
404
404
use dashmap:: DashMap ;
405
- use deadpool:: managed:: { Manager as ManagerTrait , RecycleError , RecycleResult } ;
405
+ use deadpool:: managed:: { Manager as ManagerTrait , RecycleResult } ;
406
406
use thiserror:: Error ;
407
407
408
408
use crate :: db:: redis_connection;
@@ -420,6 +420,7 @@ pub mod redis_pool {
420
420
#[ derive( Clone ) ]
421
421
pub struct Database {
422
422
available : bool ,
423
+ index : u8 ,
423
424
pub connection : MultiplexedConnection ,
424
425
}
425
426
@@ -475,6 +476,8 @@ pub mod redis_pool {
475
476
pub enum Error {
476
477
#[ error( "A redis error occurred" ) ]
477
478
Redis ( #[ from] RedisError ) ,
479
+ #[ error( "Creation of new database connection failed" ) ]
480
+ CreationFailed ,
478
481
}
479
482
480
483
#[ async_trait]
@@ -483,45 +486,58 @@ pub mod redis_pool {
483
486
type Error = Error ;
484
487
485
488
async fn create ( & self ) -> Result < Self :: Type , Self :: Error > {
486
- loop {
487
- for mut record in self . connections . iter_mut ( ) {
488
- let database = record. value_mut ( ) . as_mut ( ) ;
489
-
490
- match database {
491
- Some ( database) if database. available => {
492
- database. available = false ;
493
- return Ok ( database. clone ( ) ) ;
494
- }
495
- // if Some but not available, skip it
496
- Some ( _) => continue ,
497
- None => {
498
- let mut redis_conn =
499
- redis_connection ( & format ! ( "{}{}" , Self :: URL , record. key( ) ) ) . await ?;
500
-
501
- // run `FLUSHDB` to clean any leftovers of previous tests
502
- // even from different test runs as there might be leftovers
503
- Self :: flush_db ( & mut redis_conn) . await ?;
504
-
505
- let database = Database {
506
- available : false ,
507
- connection : redis_conn,
508
- } ;
509
-
510
- * record. value_mut ( ) = Some ( database. clone ( ) ) ;
511
-
512
- return Ok ( database) ;
513
- }
489
+ for mut record in self . connections . iter_mut ( ) {
490
+ let database = record. value_mut ( ) . as_mut ( ) ;
491
+
492
+ match database {
493
+ Some ( database) if database. available => {
494
+ database. available = false ;
495
+ return Ok ( database. clone ( ) ) ;
496
+ }
497
+ // if Some but not available, skip it
498
+ Some ( database) if !database. available => continue ,
499
+ // if there is no connection or it's available
500
+ // always create a new redis connection because of a known issue in redis
501
+ // see https://github.com/mitsuhiko/redis-rs/issues/325
502
+ _ => {
503
+ let mut redis_conn =
504
+ redis_connection ( & format ! ( "{}{}" , Self :: URL , record. key( ) ) )
505
+ . await
506
+ . expect ( "Should connect" ) ;
507
+
508
+ // run `FLUSHDB` to clean any leftovers of previous tests
509
+ // even from different test runs as there might be leftovers
510
+ // flush never fails as an operation
511
+ Self :: flush_db ( & mut redis_conn) . await . expect ( "Should flush" ) ;
512
+
513
+ let database = Database {
514
+ available : false ,
515
+ index : * record. key ( ) ,
516
+ connection : redis_conn,
517
+ } ;
518
+
519
+ * record. value_mut ( ) = Some ( database. clone ( ) ) ;
520
+
521
+ return Ok ( database) ;
514
522
}
515
523
}
516
524
}
525
+
526
+ Err ( Error :: CreationFailed )
517
527
}
518
528
519
529
async fn recycle ( & self , database : & mut Database ) -> RecycleResult < Self :: Error > {
520
- // run `FLUSHDB` to clean any leftovers of previous tests
521
- Self :: flush_db ( & mut database. connection )
530
+ // always make a new connection because of know redis crate issue
531
+ // see https://github.com/mitsuhiko/redis-rs/issues/325
532
+ let connection = redis_connection ( & format ! ( "{}{}" , Self :: URL , database. index) )
522
533
. await
523
- . map_err ( RecycleError :: Backend ) ?;
534
+ . expect ( "Should connect" ) ;
535
+ // make the database available
524
536
database. available = true ;
537
+ database. connection = connection;
538
+ Self :: flush_db ( & mut database. connection )
539
+ . await
540
+ . expect ( "Should flush" ) ;
525
541
526
542
Ok ( ( ) )
527
543
}
0 commit comments