@@ -174,6 +174,11 @@ class ValkeyCluster(AbstractValkey, AbstractValkeyCluster, AsyncValkeyClusterCom
174174 maximum number of connections are already created, a
175175 :class:`~.MaxConnectionsError` is raised. This error may be retried as defined
176176 by :attr:`connection_error_retry_attempts`
177+ :param min_connections:
178+ | Minimum number of connections per node to pre-create when the cluster is
179+ initialized. These connections are eagerly connected during cluster setup,
180+ reducing latency on the first requests. Must be less than or equal to
181+ ``max_connections``. Defaults to 0.
177182 :param address_remap:
178183 | An optional callable which, when provided with an internal network
179184 address of a node, e.g. a `(host, port)` tuple, will return the address
@@ -255,6 +260,7 @@ def __init__(
255260 cluster_error_retry_attempts : int = 3 ,
256261 connection_error_retry_attempts : int = 3 ,
257262 max_connections : int = 2 ** 31 ,
263+ min_connections : int = 0 ,
258264 # Client related kwargs
259265 db : Union [str , int ] = 0 ,
260266 path : Optional [str ] = None ,
@@ -317,6 +323,7 @@ def __init__(
317323
318324 kwargs : Dict [str , Any ] = {
319325 "max_connections" : max_connections ,
326+ "min_connections" : min_connections ,
320327 "connection_class" : Connection ,
321328 "parser_class" : ClusterParser ,
322329 # Client related kwargs
@@ -979,6 +986,7 @@ class ClusterNode:
979986 "connection_kwargs" ,
980987 "host" ,
981988 "max_connections" ,
989+ "min_connections" ,
982990 "name" ,
983991 "port" ,
984992 "response_callbacks" ,
@@ -992,12 +1000,18 @@ def __init__(
9921000 server_type : Optional [str ] = None ,
9931001 * ,
9941002 max_connections : int = 2 ** 31 ,
1003+ min_connections : int = 0 ,
9951004 connection_class : Type [Connection ] = Connection ,
9961005 ** connection_kwargs : Any ,
9971006 ) -> None :
9981007 if host == "localhost" :
9991008 host = socket .gethostbyname (host )
10001009
1010+ if min_connections > max_connections :
1011+ raise ValkeyClusterException (
1012+ '"min_connections" must be less than or equal to "max_connections"'
1013+ )
1014+
10011015 connection_kwargs ["host" ] = host
10021016 connection_kwargs ["port" ] = port
10031017 self .host = host
@@ -1006,13 +1020,28 @@ def __init__(
10061020 self .server_type = server_type
10071021
10081022 self .max_connections = max_connections
1023+ self .min_connections = min_connections
10091024 self .connection_class = connection_class
10101025 self .connection_kwargs = connection_kwargs
10111026 self .response_callbacks = connection_kwargs .pop ("response_callbacks" , {})
10121027
10131028 self ._connections : List [Connection ] = []
10141029 self ._free : Deque [Connection ] = collections .deque (maxlen = self .max_connections )
10151030
1031+ # Pre-create min_connections connection objects
1032+ for _ in range (self .min_connections ):
1033+ connection = self .connection_class (** self .connection_kwargs )
1034+ self ._connections .append (connection )
1035+ self ._free .append (connection )
1036+
1037+ async def initialize (self ) -> None :
1038+ """Connect all pre-created connections from min_connections."""
1039+ if not self ._connections :
1040+ return
1041+ await asyncio .gather (
1042+ * (connection .connect () for connection in self ._connections )
1043+ )
1044+
10161045 def __repr__ (self ) -> str :
10171046 return (
10181047 f"[host={ self .host } , port={ self .port } , "
@@ -1415,6 +1444,9 @@ async def initialize(self) -> None:
14151444 # If initialize was called after a MovedError, clear it
14161445 self ._moved_exception = None
14171446
1447+ # Eagerly connect min_connections for each node
1448+ await asyncio .gather (* (node .initialize () for node in self .nodes_cache .values ()))
1449+
14181450 async def aclose (self , attr : str = "nodes_cache" ) -> None :
14191451 self .default_node = None
14201452 await asyncio .gather (
0 commit comments