1616Connection pooling and host management.
1717"""
1818from concurrent .futures import Future
19- from functools import total_ordering
19+ from functools import total_ordering , partial
2020import logging
2121import socket
2222import time
@@ -402,7 +402,6 @@ def __init__(self, host, host_distance, session):
402402 # this is used in conjunction with the connection streams. Not using the connection lock because the connection can be replaced in the lifetime of the pool.
403403 self ._stream_available_condition = Condition (Lock ())
404404 self ._is_replacing = False
405- self ._connecting = set ()
406405 self ._connections = {}
407406 self ._pending_connections = []
408407 # A pool of additional connections which are not used but affect how Scylla
@@ -418,7 +417,6 @@ def __init__(self, host, host_distance, session):
418417 # and are waiting until all requests time out or complete
419418 # so that we can dispose of them.
420419 self ._trash = set ()
421- self ._shard_connections_futures = []
422420 self .advanced_shardaware_block_until = 0
423421
424422 if host_distance == HostDistance .IGNORED :
@@ -483,25 +481,25 @@ def _get_connection_for_routing_key(self, routing_key=None, keyspace=None, table
483481 self .host ,
484482 routing_key
485483 )
486- if conn .orphaned_threshold_reached and shard_id not in self . _connecting :
484+ if conn .orphaned_threshold_reached :
487485 # The connection has met its orphaned stream ID limit
488486 # and needs to be replaced. Start opening a connection
489487 # to the same shard and replace when it is opened.
490- self ._connecting . add ( shard_id )
491- self ._session . submit (self ._open_connection_to_missing_shard , shard_id )
488+ self ._session . shard_connection_backoff_scheduler . schedule (
489+ self .host . host_id , shard_id , partial (self ._open_connection_to_missing_shard , shard_id ) )
492490 log .debug (
493- "Connection to shard_id=%i reached orphaned stream limit, replacing on host %s (%s/%i)" ,
491+ "Scheduling Connection to shard_id=%i reached orphaned stream limit, replacing on host %s (%s/%i)" ,
494492 shard_id ,
495493 self .host ,
496494 len (self ._connections .keys ()),
497495 self .host .sharding_info .shards_count
498496 )
499- elif shard_id not in self . _connecting :
497+ else :
500498 # rate controlled optimistic attempt to connect to a missing shard
501- self ._connecting . add ( shard_id )
502- self ._session . submit (self ._open_connection_to_missing_shard , shard_id )
499+ self ._session . shard_connection_backoff_scheduler . schedule (
500+ self .host . host_id , shard_id , partial (self ._open_connection_to_missing_shard , shard_id ) )
503501 log .debug (
504- "Trying to connect to missing shard_id=%i on host %s (%s/%i)" ,
502+ "Scheduling connection to missing shard_id=%i on host %s (%s/%i)" ,
505503 shard_id ,
506504 self .host ,
507505 len (self ._connections .keys ()),
@@ -609,8 +607,8 @@ def _replace(self, connection):
609607 if connection .features .shard_id in self ._connections .keys ():
610608 del self ._connections [connection .features .shard_id ]
611609 if self .host .sharding_info and not self ._session .cluster .shard_aware_options .disable :
612- self ._connecting . add ( connection . features . shard_id )
613- self ._session . submit (self ._open_connection_to_missing_shard , connection .features .shard_id )
610+ self ._session . shard_connection_backoff_scheduler . schedule (
611+ self .host . host_id , connection . features . shard_id , partial (self ._open_connection_to_missing_shard , connection .features .shard_id ) )
614612 else :
615613 connection = self ._session .cluster .connection_factory (self .host .endpoint ,
616614 on_orphaned_stream_released = self .on_orphaned_stream_released )
@@ -635,9 +633,6 @@ def shutdown(self):
635633 with self ._stream_available_condition :
636634 self ._stream_available_condition .notify_all ()
637635
638- for future in self ._shard_connections_futures :
639- future .cancel ()
640-
641636 connections_to_close = self ._connections .copy ()
642637 pending_connections_to_close = self ._pending_connections .copy ()
643638 self ._connections .clear ()
@@ -843,7 +838,6 @@ def _open_connection_to_missing_shard(self, shard_id):
843838 self ._excess_connections .add (conn )
844839 if close_connection :
845840 conn .close ()
846- self ._connecting .discard (shard_id )
847841
848842 def _open_connections_for_all_shards (self , skip_shard_id = None ):
849843 """
@@ -856,10 +850,8 @@ def _open_connections_for_all_shards(self, skip_shard_id=None):
856850 for shard_id in range (self .host .sharding_info .shards_count ):
857851 if skip_shard_id is not None and skip_shard_id == shard_id :
858852 continue
859- future = self ._session .submit (self ._open_connection_to_missing_shard , shard_id )
860- if isinstance (future , Future ):
861- self ._connecting .add (shard_id )
862- self ._shard_connections_futures .append (future )
853+ self ._session .shard_connection_backoff_scheduler .schedule (
854+ self .host .host_id , shard_id , partial (self ._open_connection_to_missing_shard , shard_id ))
863855
864856 trash_conns = None
865857 with self ._lock :
0 commit comments