[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:
@@ -423,14 +423,30 @@ class CoroutinePool(pools.Pool):
|
|||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
recvd = sender.wait()
|
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()
|
sender = event()
|
||||||
(evt, func, args, kw) = recvd
|
(evt, func, args, kw) = recvd
|
||||||
self._safe_apply(evt, func, args, kw)
|
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())
|
api.get_hub().runloop.cancel_timers(api.getcurrent())
|
||||||
self.put(sender)
|
self.put(sender)
|
||||||
finally:
|
finally:
|
||||||
# if we get here, something broke badly, and all we can really
|
# 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())
|
self.put(self.create())
|
||||||
|
|
||||||
def _safe_apply(self, evt, func, args, kw):
|
def _safe_apply(self, evt, func, args, kw):
|
||||||
|
@@ -91,6 +91,8 @@ class BaseConnectionPool(Pool):
|
|||||||
# it's dead or None
|
# it's dead or None
|
||||||
try:
|
try:
|
||||||
conn.rollback()
|
conn.rollback()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
raise
|
||||||
except AttributeError, e:
|
except AttributeError, e:
|
||||||
# this means it's already been destroyed, so we don't need to print anything
|
# this means it's already been destroyed, so we don't need to print anything
|
||||||
conn = None
|
conn = None
|
||||||
@@ -114,6 +116,20 @@ class BaseConnectionPool(Pool):
|
|||||||
else:
|
else:
|
||||||
self.current_size -= 1
|
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):
|
class SaranwrappedConnectionPool(BaseConnectionPool):
|
||||||
"""A pool which gives out saranwrapped database connections from a pool
|
"""A pool which gives out saranwrapped database connections from a pool
|
||||||
|
Reference in New Issue
Block a user