Skip to content

Commit e2d430d

Browse files
committed
Hold reference to prepared stmt while executing
Since we use a weak-reference dict for caching prepared statements, we need to make sure at least one reference is held during executing to avoid it being GC'ed.
1 parent 7fadddc commit e2d430d

1 file changed

Lines changed: 15 additions & 5 deletions

File tree

cassandra/cluster.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,7 @@ def _prepare_all_queries(self, host):
779779
responses = connection.wait_for_responses(*messages, timeout=2.0)
780780
for response in responses:
781781
if (not isinstance(response, ResultMessage) or
782-
response.kind != ResultMessage.KIND_PREPARED):
782+
response.kind != ResultMessage.KIND_PREPARED):
783783
log.debug("Got unexpected response when preparing "
784784
"statement on host %s: %r", host, response)
785785

@@ -932,9 +932,11 @@ def execute_async(self, query, parameters=None, trace=False):
932932
... log.exception("Operation failed:")
933933
934934
"""
935+
prepared_statement = None
935936
if isinstance(query, basestring):
936937
query = SimpleStatement(query)
937938
elif isinstance(query, PreparedStatement):
939+
prepared_statement = query
938940
query = query.bind(parameters)
939941

940942
if isinstance(query, BoundStatement):
@@ -951,7 +953,9 @@ def execute_async(self, query, parameters=None, trace=False):
951953
if trace:
952954
message.tracing = True
953955

954-
future = ResponseFuture(self, message, query, metrics=self._metrics)
956+
future = ResponseFuture(
957+
self, message, query, metrics=self._metrics,
958+
prepared_statement=prepared_statement)
955959
future.send_request()
956960
return future
957961

@@ -1544,7 +1548,7 @@ def _signal_error(self):
15441548
# that errors have already been reported, so we're fine
15451549
if host:
15461550
self._cluster.signal_connection_failure(
1547-
host, self._connection.last_error, is_host_addition=False)
1551+
host, self._connection.last_error, is_host_addition=False)
15481552
return
15491553

15501554
# if the connection is not defunct or the host already left, reconnect
@@ -1670,12 +1674,13 @@ class ResponseFuture(object):
16701674
_start_time = None
16711675
_metrics = None
16721676

1673-
def __init__(self, session, message, query, metrics=None):
1677+
def __init__(self, session, message, query, metrics=None, prepared_statement=None):
16741678
self.session = session
16751679
self.row_factory = session.row_factory
16761680
self.message = message
16771681
self.query = query
16781682
self._metrics = metrics
1683+
self.prepared_statement = prepared_statement
16791684
if metrics is not None:
16801685
self._start_time = time.time()
16811686

@@ -1823,7 +1828,12 @@ def _set_result(self, response):
18231828
try:
18241829
prepared_statement = self.session.cluster._prepared_statements[query_id]
18251830
except KeyError:
1826-
log.error("Tried to execute unknown prepared statement %s", query_id.encode('hex'))
1831+
if self.prepared_statement:
1832+
query_string = ", " + self.prepared_statement.query_string
1833+
else:
1834+
query_string = ""
1835+
log.error("Tried to execute unknown prepared statement: id=%s%s",
1836+
query_id.encode('hex'), query_string)
18271837
self._set_final_exception(response)
18281838
return
18291839

0 commit comments

Comments
 (0)