Skip to content

Commit d0751e6

Browse files
avelanariusfruch
authored andcommitted
pool: call cluster.on_down() after pool shutdown()
In this commit, a logic in return_connection() is modified. This particular piece of code is executed when a connection is being closed or it is defunct. The on_down() call is a call to method decorated with @run_in_executor, meaning it can be executed in a separate thread. The shutdown() call is a synchronous method. This can cause a race: - If shutdown() is executed before on_down(), then on_down() will see there are no valid connections and will reconnect. This is good. - But if on_down() is faster and is executed before shutdown(), the on_down() method will see that there is still a valid connection in the pool (because the pool wasn't shut down) and will NOT reconnect. Afterwards, the shutdown() completes and there are no valid connections in the pool. After that, you will not be able to send queries to that host, as it will result in "ConnectionException('Pool is shutdown')" exception. The problem is fixed in this commit by moving on_down() calls after a call to shutdown(). Because shutdown() is a synchronous method, this means that first shutdown() is executed and then on_down() is executed. This is the first case described in the previous paragraph and it is a correct order. You can also think about this change as a reduction from two possible orderings (shutdown(), on_down() or on_down(), shutdown()) to a single possible ordering (shutdown(), on_down()). Fixes #170
1 parent cdeb396 commit d0751e6

File tree

1 file changed

+1
-3
lines changed

1 file changed

+1
-3
lines changed

cassandra/pool.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -543,16 +543,14 @@ def return_connection(self, connection, stream_was_orphaned=False):
543543
log.debug("Defunct or closed connection (%s) returned to pool, potentially "
544544
"marking host %s as down", id(connection), self.host)
545545
is_down = self.host.signal_connection_failure(connection.last_error)
546-
if is_down:
547-
self._session.cluster.on_down(self.host, False, False)
548546
connection.signaled_error = True
549547

550548
if self.shutdown_on_error and not is_down:
551549
is_down = True
552-
self._session.cluster.on_down(self.host, is_host_addition=False)
553550

554551
if is_down:
555552
self.shutdown()
553+
self._session.cluster.on_down(self.host, is_host_addition=False)
556554
else:
557555
connection.close()
558556
with self._lock:

0 commit comments

Comments
 (0)