Skip to content

Commit 46c6b3b

Browse files
committed
perf: lazily initialize ResponseFuture._errors dict
Change _errors initialization from {} to None, with a _add_error() helper that creates the dict on first use. This saves one dict allocation (~232 bytes on CPython) per successful query, which is the overwhelmingly common case. On the read side, the single consumer (NoHostAvailable) uses 'self._errors or {}' to handle the None case. The falsy check in _send_request_on_next_host() works unchanged since None is falsy.
1 parent 8e6c4d4 commit 46c6b3b

1 file changed

Lines changed: 15 additions & 9 deletions

File tree

cassandra/cluster.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4462,13 +4462,19 @@ def __init__(self, session, message, query, timeout, metrics=None, prepared_stat
44624462
self._spec_execution_plan = speculative_execution_plan or self._spec_execution_plan
44634463
self._make_query_plan()
44644464
self._event = Event()
4465-
self._errors = {}
4465+
self._errors = None
44664466
self._callbacks = []
44674467
self._errbacks = []
44684468
self.attempted_hosts = []
44694469
self._start_timer()
44704470
self._continuous_paging_state = continuous_paging_state
44714471

4472+
def _add_error(self, host, error):
4473+
errors = self._errors
4474+
if errors is None:
4475+
self._errors = errors = {}
4476+
errors[host] = error
4477+
44724478
@property
44734479
def _time_remaining(self):
44744480
if self.timeout is None:
@@ -4592,7 +4598,7 @@ def send_request(self, error_no_hosts=True):
45924598
return True
45934599
if error_no_hosts:
45944600
self._set_final_exception(NoHostAvailable(
4595-
"Unable to complete the operation against any hosts", self._errors))
4601+
"Unable to complete the operation against any hosts", self._errors or {}))
45964602
return False
45974603

45984604
def _query(self, host, message=None, cb=None):
@@ -4601,10 +4607,10 @@ def _query(self, host, message=None, cb=None):
46014607

46024608
pool = self.session._pools.get(host)
46034609
if not pool:
4604-
self._errors[host] = ConnectionException("Host has been marked down or removed")
4610+
self._add_error(host, ConnectionException("Host has been marked down or removed"))
46054611
return None
46064612
elif pool.is_shutdown:
4607-
self._errors[host] = ConnectionException("Pool is shutdown")
4613+
self._add_error(host, ConnectionException("Pool is shutdown"))
46084614
return None
46094615

46104616
self._current_host = host
@@ -4630,13 +4636,13 @@ def _query(self, host, message=None, cb=None):
46304636
return request_id
46314637
except NoConnectionsAvailable as exc:
46324638
log.debug("All connections for host %s are at capacity, moving to the next host", host)
4633-
self._errors[host] = exc
4639+
self._add_error(host, exc)
46344640
except ConnectionBusy as exc:
46354641
log.debug("Connection for host %s is busy, moving to the next host", host)
4636-
self._errors[host] = exc
4642+
self._add_error(host, exc)
46374643
except Exception as exc:
46384644
log.debug("Error querying host %s", host, exc_info=True)
4639-
self._errors[host] = exc
4645+
self._add_error(host, exc)
46404646
if self._metrics is not None:
46414647
self._metrics.on_connection_error()
46424648
if connection:
@@ -4949,7 +4955,7 @@ def _execute_after_prepare(self, host, connection, pool, response):
49494955
log.debug("Connection error when preparing statement on host %s: %s",
49504956
host, response)
49514957
# try again on a different host, preparing again if necessary
4952-
self._errors[host] = response
4958+
self._add_error(host, response)
49534959
self.send_request()
49544960
else:
49554961
self._set_final_exception(ConnectionException(
@@ -5023,7 +5029,7 @@ def exception_from_response(response):
50235029
self._metrics.on_ignore()
50245030
self._set_final_result(None)
50255031

5026-
self._errors[host] = exception_from_response(response)
5032+
self._add_error(host, exception_from_response(response))
50275033

50285034
def _retry(self, reuse_connection, consistency_level, host, delay):
50295035
if self._final_exception:

0 commit comments

Comments
 (0)