Skip to content

Commit be42231

Browse files
committed
cluster: keep failed add cleanup fenced
1 parent 880b0a6 commit be42231

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

cassandra/cluster.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1873,13 +1873,15 @@ def _cleanup_failed_on_up_handling(self, host):
18731873
def _cleanup_failed_on_add_handling(self, host):
18741874
with host.lock:
18751875
host.set_down()
1876-
host._currently_handling_node_addition = False
18771876

18781877
self.profile_manager.on_down(host)
18791878
self.control_connection.on_down(host)
18801879
for session in tuple(self.sessions):
18811880
session.remove_pool(host)
18821881

1882+
with host.lock:
1883+
host._currently_handling_node_addition = False
1884+
18831885
self._start_reconnector(host, is_host_addition=True)
18841886

18851887
def _on_up_future_completed(self, host, futures, results, lock, finished_future):

tests/unit/test_cluster.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,37 @@ def test_on_add_excludes_host_from_query_plan_when_pool_future_fails(self):
146146
finally:
147147
cluster.shutdown()
148148

149+
def test_on_add_failure_does_not_allow_reentrant_add_during_cleanup(self):
150+
cluster = Cluster(protocol_version=4)
151+
host = Host("127.0.0.1", SimpleConvictionPolicy, datacenter="dc1", rack="rack1", host_id=uuid.uuid4())
152+
failed_future = Future()
153+
successful_future = Future()
154+
successful_future.set_result(True)
155+
session = Mock()
156+
session.add_or_renew_pool.side_effect = [failed_future, successful_future]
157+
session.update_created_pools.return_value = set()
158+
cluster.sessions = [session]
159+
160+
original_on_down = cluster.profile_manager.on_down
161+
162+
def reentrant_add_while_cleanup_removes_host(cleanup_host):
163+
cluster.on_add(host, refresh_nodes=False)
164+
original_on_down(cleanup_host)
165+
166+
cluster.profile_manager.on_down = Mock(side_effect=reentrant_add_while_cleanup_removes_host)
167+
168+
try:
169+
cluster.on_add(host, refresh_nodes=False)
170+
171+
failed_future.set_result(False)
172+
173+
load_balancer = cluster.profile_manager.default.load_balancing_policy
174+
assert host not in list(load_balancer.make_query_plan())
175+
assert host.is_up is False
176+
assert session.add_or_renew_pool.call_count == 1
177+
finally:
178+
cluster.shutdown()
179+
149180
def test_on_add_waits_for_all_session_pool_futures_before_marking_host_up(self):
150181
cluster = Cluster(protocol_version=4)
151182
host = Host("127.0.0.1", SimpleConvictionPolicy, host_id=uuid.uuid4())

0 commit comments

Comments
 (0)