Skip to content

Commit 77d69ed

Browse files
committed
session: reject stale same-endpoint pool creation
1 parent c2275c9 commit 77d69ed

2 files changed

Lines changed: 44 additions & 2 deletions

File tree

cassandra/cluster.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4191,10 +4191,18 @@ def callback(pool, errors):
41914191
metadata_host = host
41924192
if isinstance(self.cluster.metadata, Metadata):
41934193
metadata_host = self.cluster.metadata.get_host_by_host_id(host.host_id)
4194+
if metadata_host is None:
4195+
log.debug(
4196+
"Discarding stale connection pool for host %s; "
4197+
"host id is no longer present in metadata",
4198+
host)
4199+
self._invalidate_pool_creation(
4200+
host, expected_endpoint=creation_endpoint)
4201+
discard_pool = True
41944202

41954203
target_host = metadata_host if metadata_host is not None else host
41964204
target_endpoint_changed = False
4197-
if target_host is not host:
4205+
if not discard_pool and target_host is not host:
41984206
with target_host.lock:
41994207
target_endpoint_changed = not self._endpoints_match(
42004208
target_host.endpoint, creation_endpoint)
@@ -4207,7 +4215,8 @@ def callback(pool, errors):
42074215
self._invalidate_pool_creation(
42084216
host, expected_endpoint=creation_endpoint)
42094217
discard_pool = True
4210-
else:
4218+
4219+
if not discard_pool:
42114220
target_host_matches = False
42124221
for pool_host in tuple(retained_pools):
42134222
if pool_host is target_host:

tests/unit/test_cluster.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,37 @@ def make_pool(host, distance, pool_session, endpoint=None):
726726
assert session._pools == {}
727727
created_pools[0].shutdown.assert_called_once_with()
728728

729+
def test_stale_host_pool_creation_does_not_replace_same_endpoint_host(self):
730+
endpoint = DefaultEndPoint("127.0.0.1")
731+
stale_host = Host(endpoint, SimpleConvictionPolicy,
732+
host_id=uuid.uuid4())
733+
replacement_host = Host(endpoint, SimpleConvictionPolicy,
734+
host_id=uuid.uuid4())
735+
cluster, session, executor = self._make_cluster_and_session(
736+
[replacement_host])
737+
cluster.metadata = Metadata()
738+
cluster.metadata.add_or_return_host(replacement_host)
739+
replacement_pool = self._make_pool(
740+
replacement_host, HostDistance.LOCAL, session)
741+
session._pools[replacement_host] = replacement_pool
742+
created_pools = []
743+
744+
def make_pool(host, distance, pool_session, endpoint=None):
745+
pool = self._make_pool(host, distance, pool_session, endpoint)
746+
created_pools.append(pool)
747+
return pool
748+
749+
with patch("cassandra.cluster.HostConnection", side_effect=make_pool):
750+
future = session.add_or_renew_pool(
751+
stale_host, is_host_addition=False)
752+
753+
executor.run_next()
754+
755+
assert future.result() is False
756+
assert session._pools[replacement_host] is replacement_pool
757+
replacement_pool.shutdown.assert_not_called()
758+
created_pools[0].shutdown.assert_called_once_with()
759+
729760
def test_remove_pool_expected_host_mismatch_invalidates_stale_creation(self):
730761
stale_host = self._make_host("127.0.0.1")
731762
replacement_host = self._make_host("127.0.0.1")
@@ -1072,6 +1103,8 @@ def _make_session_with_pool(host, pool):
10721103
session = Session.__new__(Session)
10731104
session._lock = Lock()
10741105
session._pools = {host: pool}
1106+
session.cluster = Mock()
1107+
session.cluster.metadata.all_hosts.return_value = []
10751108
session.submit = _ImmediateExecutor().submit
10761109
return session
10771110

0 commit comments

Comments
 (0)