55
66from redis .asyncio .client import Redis
77from redis .asyncio .connection import (
8+ BlockingConnectionPool ,
89 Connection ,
910 ConnectionPool ,
1011 EncodableT ,
@@ -203,12 +204,38 @@ async def get_master_address(self):
203204 def rotate_slaves (self ) -> AsyncIterator :
204205 """Round-robin slave balancer"""
205206 return self .proxy .rotate_slaves ()
207+
208+
209+ class SentinelBlockingConnectionPool (BlockingConnectionPool ):
210+ """
211+ Sentinel blocking connection pool.
212+
213+ If ``check_connection`` flag is set to True, SentinelManagedConnection
214+ sends a PING command right after establishing the connection.
215+ """
216+
217+ def __init__ (self , service_name , sentinel_manager , ** kwargs ):
218+ kwargs ["connection_class" ] = kwargs .get (
219+ "connection_class" ,
220+ (
221+ SentinelManagedSSLConnection
222+ if kwargs .pop ("ssl" , False )
223+ else SentinelManagedConnection
224+ ),
225+ )
226+ self .is_master = kwargs .pop ("is_master" , True )
227+ self .check_connection = kwargs .pop ("check_connection" , False )
228+ self .proxy = SentinelConnectionPoolProxy (
229+ connection_pool = self ,
230+ is_master = self .is_master ,
231+ check_connection = self .check_connection ,
232+ service_name = service_name ,
233+ sentinel_manager = sentinel_manager ,
234+ )
206235 super ().__init__ (** kwargs )
207236 self .connection_kwargs ["connection_pool" ] = weakref .proxy (self )
208237 self .service_name = service_name
209238 self .sentinel_manager = sentinel_manager
210- self .master_address = None
211- self .slave_rr_counter = None
212239
213240 def __repr__ (self ):
214241 return (
@@ -218,8 +245,11 @@ def __repr__(self):
218245
219246 def reset (self ):
220247 super ().reset ()
221- self .master_address = None
222- self .slave_rr_counter = None
248+ self .proxy .reset ()
249+
250+ @property
251+ def master_address (self ):
252+ return self .proxy .master_address
223253
224254 def owns_connection (self , connection : Connection ):
225255 check = not self .is_master or (
@@ -228,31 +258,11 @@ def owns_connection(self, connection: Connection):
228258 return check and super ().owns_connection (connection )
229259
230260 async def get_master_address (self ):
231- master_address = await self .sentinel_manager .discover_master (self .service_name )
232- if self .is_master :
233- if self .master_address != master_address :
234- self .master_address = master_address
235- # disconnect any idle connections so that they reconnect
236- # to the new master the next time that they are used.
237- await self .disconnect (inuse_connections = False )
238- return master_address
261+ return await self .proxy .get_master_address ()
239262
240- async def rotate_slaves (self ) -> AsyncIterator :
263+ def rotate_slaves (self ) -> AsyncIterator :
241264 """Round-robin slave balancer"""
242- slaves = await self .sentinel_manager .discover_slaves (self .service_name )
243- if slaves :
244- if self .slave_rr_counter is None :
245- self .slave_rr_counter = random .randint (0 , len (slaves ) - 1 )
246- for _ in range (len (slaves )):
247- self .slave_rr_counter = (self .slave_rr_counter + 1 ) % len (slaves )
248- slave = slaves [self .slave_rr_counter ]
249- yield slave
250- # Fallback to the master connection
251- try :
252- yield await self .get_master_address ()
253- except MasterNotFoundError :
254- pass
255- raise SlaveNotFoundError (f"No slave found for { self .service_name !r} " )
265+ return self .proxy .rotate_slaves ()
256266
257267
258268class Sentinel (AsyncSentinelCommands ):
0 commit comments