1
1
mod cluster;
2
2
3
+ use std:: time:: Duration ;
4
+
3
5
use bb8:: { Pool , RunError } ;
4
- use bb8_redis:: RedisMultiplexedConnectionManager ;
6
+ use bb8_redis:: RedisConnectionManager ;
5
7
use redis:: { FromRedisValue , RedisError , RedisResult } ;
6
8
7
9
pub use self :: cluster:: RedisClusterConnectionManager ;
8
10
use crate :: cfg:: Configuration ;
9
11
12
+ pub const REDIS_CONN_TIMEOUT : Duration = Duration :: from_secs ( 2 ) ;
13
+
10
14
#[ derive( Clone , Debug ) ]
11
15
pub enum RedisPool {
12
16
Clustered ( ClusteredRedisPool ) ,
17
+ ClusteredUnpooled ( ClusteredRedisUnpooled ) ,
13
18
NonClustered ( NonClusteredRedisPool ) ,
14
19
}
15
20
@@ -18,6 +23,7 @@ impl RedisPool {
18
23
match self {
19
24
Self :: Clustered ( pool) => pool. get ( ) . await ,
20
25
Self :: NonClustered ( pool) => pool. get ( ) . await ,
26
+ Self :: ClusteredUnpooled ( pool) => pool. get ( ) . await ,
21
27
}
22
28
}
23
29
}
@@ -36,9 +42,30 @@ impl ClusteredRedisPool {
36
42
}
37
43
}
38
44
45
+ #[ derive( Clone ) ]
46
+ pub struct ClusteredRedisUnpooled {
47
+ con : redis:: cluster_async:: ClusterConnection ,
48
+ }
49
+
50
+ impl ClusteredRedisUnpooled {
51
+ pub async fn get ( & self ) -> Result < PooledConnection < ' _ > , RunError < RedisError > > {
52
+ Ok ( PooledConnection :: ClusteredUnpooled (
53
+ ClusteredUnpooledConnection {
54
+ con : self . con . clone ( ) ,
55
+ } ,
56
+ ) )
57
+ }
58
+ }
59
+
60
+ impl std:: fmt:: Debug for ClusteredRedisUnpooled {
61
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
62
+ f. debug_struct ( "ClusteredRedisUnpooled" ) . finish ( )
63
+ }
64
+ }
65
+
39
66
#[ derive( Clone , Debug ) ]
40
67
pub struct NonClusteredRedisPool {
41
- pool : Pool < RedisMultiplexedConnectionManager > ,
68
+ pool : Pool < RedisConnectionManager > ,
42
69
}
43
70
44
71
impl NonClusteredRedisPool {
@@ -51,6 +78,7 @@ impl NonClusteredRedisPool {
51
78
52
79
pub enum PooledConnection < ' a > {
53
80
Clustered ( ClusteredPooledConnection < ' a > ) ,
81
+ ClusteredUnpooled ( ClusteredUnpooledConnection ) ,
54
82
NonClustered ( NonClusteredPooledConnection < ' a > ) ,
55
83
}
56
84
@@ -75,6 +103,7 @@ impl redis::aio::ConnectionLike for PooledConnection<'_> {
75
103
match self {
76
104
PooledConnection :: Clustered ( conn) => conn. con . req_packed_command ( cmd) ,
77
105
PooledConnection :: NonClustered ( conn) => conn. con . req_packed_command ( cmd) ,
106
+ PooledConnection :: ClusteredUnpooled ( conn) => conn. con . req_packed_command ( cmd) ,
78
107
}
79
108
}
80
109
@@ -89,19 +118,23 @@ impl redis::aio::ConnectionLike for PooledConnection<'_> {
89
118
PooledConnection :: NonClustered ( conn) => {
90
119
conn. con . req_packed_commands ( cmd, offset, count)
91
120
}
121
+ PooledConnection :: ClusteredUnpooled ( conn) => {
122
+ conn. con . req_packed_commands ( cmd, offset, count)
123
+ }
92
124
}
93
125
}
94
126
95
127
fn get_db ( & self ) -> i64 {
96
128
match self {
97
129
PooledConnection :: Clustered ( conn) => conn. con . get_db ( ) ,
98
130
PooledConnection :: NonClustered ( conn) => conn. con . get_db ( ) ,
131
+ PooledConnection :: ClusteredUnpooled ( conn) => conn. con . get_db ( ) ,
99
132
}
100
133
}
101
134
}
102
135
103
136
pub struct NonClusteredPooledConnection < ' a > {
104
- con : bb8:: PooledConnection < ' a , RedisMultiplexedConnectionManager > ,
137
+ con : bb8:: PooledConnection < ' a , RedisConnectionManager > ,
105
138
}
106
139
107
140
impl < ' a > NonClusteredPooledConnection < ' a > {
@@ -134,28 +167,73 @@ impl<'a> ClusteredPooledConnection<'a> {
134
167
}
135
168
}
136
169
137
- pub async fn new_redis_pool_clustered ( redis_dsn : & str , cfg : & Configuration ) -> RedisPool {
138
- let mgr = RedisClusterConnectionManager :: new ( redis_dsn)
139
- . expect ( "Error initializing redis cluster client" ) ;
140
- let pool = bb8:: Pool :: builder ( )
141
- . max_size ( cfg. redis_pool_max_size . into ( ) )
142
- . build ( mgr)
170
+ pub struct ClusteredUnpooledConnection {
171
+ con : redis:: cluster_async:: ClusterConnection ,
172
+ }
173
+
174
+ impl ClusteredUnpooledConnection {
175
+ pub async fn query_async < T : FromRedisValue > ( & mut self , cmd : redis:: Cmd ) -> RedisResult < T > {
176
+ cmd. query_async ( & mut self . con ) . await
177
+ }
178
+
179
+ pub async fn query_async_pipeline < T : FromRedisValue > (
180
+ & mut self ,
181
+ pipe : redis:: Pipeline ,
182
+ ) -> RedisResult < T > {
183
+ pipe. query_async ( & mut self . con ) . await
184
+ }
185
+ }
186
+
187
+ async fn new_redis_pool_helper (
188
+ redis_dsn : & str ,
189
+ clustered : bool ,
190
+ max_connections : u16 ,
191
+ ) -> RedisPool {
192
+ if clustered {
193
+ let mgr = RedisClusterConnectionManager :: new ( redis_dsn)
194
+ . expect ( "Error initializing redis cluster client" ) ;
195
+ let pool = bb8:: Pool :: builder ( )
196
+ . max_size ( max_connections. into ( ) )
197
+ . build ( mgr)
198
+ . await
199
+ . expect ( "Error initializing redis cluster connection pool" ) ;
200
+ let pool = ClusteredRedisPool { pool } ;
201
+ RedisPool :: Clustered ( pool)
202
+ } else {
203
+ let mgr = RedisConnectionManager :: new ( redis_dsn) . expect ( "Error initializing redis client" ) ;
204
+ let pool = bb8:: Pool :: builder ( )
205
+ . max_size ( max_connections. into ( ) )
206
+ . build ( mgr)
207
+ . await
208
+ . expect ( "Error initializing redis connection pool" ) ;
209
+ let pool = NonClusteredRedisPool { pool } ;
210
+ RedisPool :: NonClustered ( pool)
211
+ }
212
+ }
213
+
214
+ async fn new_redis_unpooled_helper ( redis_dsn : & str ) -> RedisPool {
215
+ let cli = redis:: cluster:: ClusterClient :: builder ( vec ! [ redis_dsn] )
216
+ . retries ( 1 )
217
+ . connection_timeout ( REDIS_CONN_TIMEOUT )
218
+ . build ( )
219
+ . expect ( "Error initializing redis-unpooled client" ) ;
220
+ let con = cli
221
+ . get_async_connection ( )
143
222
. await
144
- . expect ( "Error initializing redis cluster connection pool" ) ;
145
- let pool = ClusteredRedisPool { pool } ;
146
- RedisPool :: Clustered ( pool)
223
+ . expect ( "Failed to get redis-cluster-unpooled connection" ) ;
224
+ RedisPool :: ClusteredUnpooled ( ClusteredRedisUnpooled { con } )
225
+ }
226
+
227
+ pub async fn new_redis_pool_clustered ( redis_dsn : & str , cfg : & Configuration ) -> RedisPool {
228
+ new_redis_pool_helper ( redis_dsn, true , cfg. redis_pool_max_size ) . await
229
+ }
230
+
231
+ pub async fn new_redis_clustered_unpooled ( redis_dsn : & str ) -> RedisPool {
232
+ new_redis_unpooled_helper ( redis_dsn) . await
147
233
}
148
234
149
235
pub async fn new_redis_pool ( redis_dsn : & str , cfg : & Configuration ) -> RedisPool {
150
- let mgr =
151
- RedisMultiplexedConnectionManager :: new ( redis_dsn) . expect ( "Error initializing redis client" ) ;
152
- let pool = bb8:: Pool :: builder ( )
153
- . max_size ( cfg. redis_pool_max_size . into ( ) )
154
- . build ( mgr)
155
- . await
156
- . expect ( "Error initializing redis connection pool" ) ;
157
- let pool = NonClusteredRedisPool { pool } ;
158
- RedisPool :: NonClustered ( pool)
236
+ new_redis_pool_helper ( redis_dsn, false , cfg. redis_pool_max_size ) . await
159
237
}
160
238
161
239
#[ cfg( test) ]
@@ -168,6 +246,7 @@ mod tests {
168
246
async fn get_pool ( redis_dsn : & str , cfg : & Configuration ) -> RedisPool {
169
247
match cfg. cache_type {
170
248
CacheType :: RedisCluster => super :: new_redis_pool_clustered ( redis_dsn, cfg) . await ,
249
+ CacheType :: RedisClusterUnpooled => super :: new_redis_clustered_unpooled ( redis_dsn) . await ,
171
250
CacheType :: Redis => super :: new_redis_pool ( redis_dsn, cfg) . await ,
172
251
_ => panic ! (
173
252
"This test should only be run when redis is configured as the cache provider"
0 commit comments