From f0fc2288fc4f907d3f012f02e0c64a6093b64dfa Mon Sep 17 00:00:00 2001 From: Tyler Hobbs Date: Thu, 13 Feb 2014 12:38:49 -0600 Subject: [PATCH] Always close sockets when defuncting connections Under certain error conditions, this could result in an FD leak for the socket handles. (In my testing, they seemed to eventually be GC'ed and closed, but this behavior is probably not dependable.) Fixes #80 --- CHANGELOG.rst | 2 ++ cassandra/io/asyncorereactor.py | 5 +++-- cassandra/io/libevreactor.py | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c45ff4fd..abe56c06 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,6 +6,8 @@ Bug Fixes --------- * Include table indexes in ``KeyspaceMetadata.export_as_string()`` * Fix broken token awareness on ByteOrderedPartitioner +* Always close socket when defuncting error'ed connections to avoid a potential + file descriptor leak Other ----- diff --git a/cassandra/io/asyncorereactor.py b/cassandra/io/asyncorereactor.py index 4a956727..6fefa49d 100644 --- a/cassandra/io/asyncorereactor.py +++ b/cassandra/io/asyncorereactor.py @@ -173,11 +173,11 @@ class AsyncoreConnection(Connection, asyncore.dispatcher): with _starting_conns_lock: _starting_conns.discard(self) - # don't leave in-progress operations hanging - self.connected_event.set() if not self.is_defunct: self._error_all_callbacks( ConnectionShutdown("Connection to %s was closed" % self.host)) + # don't leave in-progress operations hanging + self.connected_event.set() def defunct(self, exc): with self.lock: @@ -194,6 +194,7 @@ class AsyncoreConnection(Connection, asyncore.dispatcher): id(self), self.host, exc) self.last_error = exc + self.close() self._error_all_callbacks(exc) self.connected_event.set() return exc diff --git a/cassandra/io/libevreactor.py b/cassandra/io/libevreactor.py index f24964bb..35fc1771 100644 --- a/cassandra/io/libevreactor.py +++ b/cassandra/io/libevreactor.py @@ -246,6 +246,7 @@ class LibevConnection(Connection): log.debug("Defuncting connection (%s) to %s: %s", id(self), self.host, exc) self.last_error = exc + self.close() self._error_all_callbacks(exc) self.connected_event.set() return exc