Skip to content

Commit f81ef1f

Browse files
Copilotmykaul
andcommitted
Fix TruncateError retry behavior - stop retrying on truncate errors
Co-authored-by: mykaul <4655593+mykaul@users.noreply.github.com>
1 parent eea71f7 commit f81ef1f

2 files changed

Lines changed: 37 additions & 6 deletions

File tree

cassandra/cluster.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5257,14 +5257,24 @@ def _set_result(self, host, connection, pool, response):
52575257
self.query, retry_num=self._query_retries, **response.info)
52585258
elif isinstance(response, (OverloadedErrorMessage,
52595259
IsBootstrappingErrorMessage,
5260-
TruncateError, ServerError)):
5260+
ServerError)):
52615261
log.warning("Host %s error: %s.", host, response.summary)
52625262
if self._metrics is not None:
52635263
self._metrics.on_other_error()
52645264
cl = getattr(self.message, 'consistency_level', None)
52655265
retry = retry_policy.on_request_error(
52665266
self.query, cl, error=response,
52675267
retry_num=self._query_retries)
5268+
elif isinstance(response, TruncateError):
5269+
# TruncateError should not be retried as it indicates a permanent failure
5270+
log.warning("Host %s truncate error: %s.", host, response.summary)
5271+
if self._metrics is not None:
5272+
self._metrics.on_other_error()
5273+
if hasattr(response, 'to_exception'):
5274+
self._set_final_exception(response.to_exception())
5275+
else:
5276+
self._set_final_exception(response)
5277+
return
52685278
elif isinstance(response, PreparedQueryNotFound):
52695279
if self.prepared_statement:
52705280
query_id = self.prepared_statement.query_id

tests/integration/simulacron/test_policies.py

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -424,14 +424,13 @@ def test_retry_policy_on_request_error(self):
424424
"message": "server_error"
425425
}
426426

427-
# Test the on_request_error call
427+
# Test the on_request_error call for errors that should retry
428428
retry_policy = CounterRetryPolicy()
429429
self.set_cluster(retry_policy)
430430

431431
for prime_error, exc in [
432432
(overloaded_error, OverloadedErrorMessage),
433433
(bootstrapping_error, IsBootstrappingErrorMessage),
434-
(truncate_error, TruncateError),
435434
(server_error, ServerError)]:
436435

437436
clear_queries()
@@ -444,13 +443,24 @@ def test_retry_policy_on_request_error(self):
444443

445444
assert len(rf.attempted_hosts) == 1 # no retry
446445

447-
assert next(retry_policy.request_error) == 4
446+
assert next(retry_policy.request_error) == 3
448447

449-
# Test that by default, retry on next host
448+
# Test TruncateError is not retried (no on_request_error call)
449+
clear_queries()
450+
query_to_prime = "SELECT * from simulacron_keyspace.simulacron_table;"
451+
prime_query(query_to_prime, then=truncate_error, rows=None, column_types=None)
452+
rf = self.session.execute_async(query_to_prime)
453+
454+
with pytest.raises(TruncateError):
455+
rf.result()
456+
457+
assert len(rf.attempted_hosts) == 1 # no retry
458+
459+
# Test that by default, errors retry on next host (except TruncateError)
450460
retry_policy = RetryPolicy()
451461
self.set_cluster(retry_policy)
452462

453-
for e in [overloaded_error, bootstrapping_error, truncate_error, server_error]:
463+
for e in [overloaded_error, bootstrapping_error, server_error]:
454464
clear_queries()
455465
query_to_prime = "SELECT * from simulacron_keyspace.simulacron_table;"
456466
prime_query(query_to_prime, then=e, rows=None, column_types=None)
@@ -460,3 +470,14 @@ def test_retry_policy_on_request_error(self):
460470
rf.result()
461471

462472
assert len(rf.attempted_hosts) == 3 # all 3 nodes failed
473+
474+
# Test TruncateError does not retry even with default RetryPolicy
475+
clear_queries()
476+
query_to_prime = "SELECT * from simulacron_keyspace.simulacron_table;"
477+
prime_query(query_to_prime, then=truncate_error, rows=None, column_types=None)
478+
rf = self.session.execute_async(query_to_prime)
479+
480+
with pytest.raises(TruncateError):
481+
rf.result()
482+
483+
assert len(rf.attempted_hosts) == 1 # no retry for TruncateError

0 commit comments

Comments
 (0)