@@ -2,11 +2,12 @@ use std::collections::HashSet;
22use std:: fmt;
33use std:: fmt:: Display ;
44use std:: str:: FromStr ;
5- use std:: sync:: Arc ;
5+ use std:: sync:: { Arc , Mutex } ;
66use std:: time:: { Duration , SystemTime } ;
77
88use async_trait:: async_trait;
99use cadence:: { CountedExt , StatsdClient } ;
10+ use redis:: aio:: MultiplexedConnection ;
1011use redis:: { AsyncCommands , SetExpiry , SetOptions } ;
1112use uuid:: Uuid ;
1213
@@ -56,6 +57,7 @@ impl<'a> From<Chanid<'a>> for String {
5657pub struct RedisClientImpl {
5758 /// Database connector string
5859 pub client : redis:: Client ,
60+ pub conn : Arc < Mutex < Option < MultiplexedConnection > > > ,
5961 pub ( crate ) settings : RedisDbSettings ,
6062 /// Metrics client
6163 metrics : Arc < StatsdClient > ,
@@ -75,6 +77,7 @@ impl RedisClientImpl {
7577
7678 Ok ( Self {
7779 client,
80+ conn : Arc :: new ( Mutex :: new ( None ) ) ,
7881 settings : db_settings,
7982 metrics,
8083 redis_opts : SetOptions :: default ( ) . with_expiration ( SetExpiry :: EX ( MAX_ROUTER_TTL ) ) ,
@@ -88,17 +91,34 @@ impl RedisClientImpl {
8891 Pools also return a ConnectionLike, so we can add support for pools later.
8992 */
9093 async fn connection ( & self ) -> DbResult < redis:: aio:: MultiplexedConnection > {
94+ {
95+ let conn = self
96+ . conn
97+ . lock ( )
98+ . map_err ( |e| DbError :: General ( e. to_string ( ) ) ) ?
99+ . clone ( ) ;
100+
101+ if let Some ( co) = conn {
102+ return Ok ( co) ;
103+ }
104+ }
91105 let config = if self . settings . timeout . is_some_and ( |t| !t. is_zero ( ) ) {
92106 redis:: AsyncConnectionConfig :: new ( )
93107 . set_connection_timeout ( self . settings . timeout . unwrap ( ) )
94108 } else {
95109 redis:: AsyncConnectionConfig :: new ( )
96110 } ;
97- Ok ( self
111+ let co = self
98112 . client
99113 . get_multiplexed_async_connection_with_config ( & config)
100114 . await
101- . map_err ( |e| DbError :: ConnectionError ( format ! ( "Cannot connect to redis: {}" , e) ) ) ?)
115+ . map_err ( |e| DbError :: ConnectionError ( format ! ( "Cannot connect to redis: {}" , e) ) ) ?;
116+ let mut conn = self
117+ . conn
118+ . lock ( )
119+ . map_err ( |e| DbError :: General ( e. to_string ( ) ) ) ?;
120+ * conn = Some ( co. clone ( ) ) ;
121+ Ok ( co)
102122 }
103123
104124 fn user_key ( & self , uaid : & Uaid ) -> String {
0 commit comments