[svn r134] Fixes for some interesting issues discovered only after our count of unit tests using database connections crested 100.

This commit is contained in:
which.linden
2008-07-03 19:41:39 -07:00
parent 4a6a3c257d
commit 757d1ff7a0
2 changed files with 33 additions and 1 deletions

View File

@@ -423,14 +423,30 @@ class CoroutinePool(pools.Pool):
try:
while True:
recvd = sender.wait()
# Delete the sender's result here because the very
# first event through the loop is referenced by
# spawn_startup, and therefore is not itself deleted.
# This means that we have to free up its argument
# because otherwise said argument persists in memory
# forever. This is generally only a problem in unit
# tests.
sender._result = NOT_USED
sender = event()
(evt, func, args, kw) = recvd
self._safe_apply(evt, func, args, kw)
# Likewise, delete these variables or else they will
# be referenced by this frame until replaced by the
# next recvd, which may or may not be a long time from
# now.
del evt, func, args, kw, recvd
api.get_hub().runloop.cancel_timers(api.getcurrent())
self.put(sender)
finally:
# if we get here, something broke badly, and all we can really
# do is try to keep the pool from leaking items
# do is try to keep the pool from leaking items.
# Shouldn't even try to print the exception.
self.put(self.create())
def _safe_apply(self, evt, func, args, kw):

View File

@@ -91,6 +91,8 @@ class BaseConnectionPool(Pool):
# it's dead or None
try:
conn.rollback()
except KeyboardInterrupt:
raise
except AttributeError, e:
# this means it's already been destroyed, so we don't need to print anything
conn = None
@@ -113,6 +115,20 @@ class BaseConnectionPool(Pool):
super(BaseConnectionPool, self).put(conn)
else:
self.current_size -= 1
def clear(self):
""" Close all connections that this pool still holds a reference to, leaving it empty."""
for conn in self.free_items:
try:
conn.close()
except KeyboardInterrupt:
raise
except:
pass # even if stuff happens here, we still want to at least try to close all the other connections
self.free_items.clear()
def __del__(self):
self.clear()
class SaranwrappedConnectionPool(BaseConnectionPool):