Commit d818fbd3 authored by Christian Theune's avatar Christian Theune

Changed the automatic garbage collection when opening a connection to only

apply the garbage collections on those connections in the pool that are
closed. (This fixed issue 113932.)
parent 13b1f7e3
......@@ -62,6 +62,10 @@ Connection management
and/or store limited resources (such as RDB connections) in connection
caches may benefit.
- (3.7.0c1) Changed the automatic garbage collection when opening a connection
to only apply the garbage collections on those connections in the pool that
are closed. (This fixed issue 113932.)
DemoStorage
-----------
......
......@@ -145,9 +145,17 @@ class _ConnectionPool(object):
assert result in self.all
return result
# For every live connection c, invoke f(c).
def map(self, f):
self.all.map(f)
def map(self, f, open_connections=True):
"""For every live connection c, invoke f(c).
If `open_connections` is false then only call f(c) on closed
connections.
"""
if open_connections:
self.all.map(f)
else:
map(f, self.available)
class DB(object):
"""The Object Database
......@@ -304,12 +312,17 @@ class DB(object):
finally:
self._r()
# Call f(c) for all connections c in all pools in all versions.
def _connectionMap(self, f):
def _connectionMap(self, f, open_connections=True):
"""Call f(c) for all connections c in all pools in all versions.
If `open_connections` is false then f(c) is only called on closed
connections.
"""
self._a()
try:
for pool in self._pools.values():
pool.map(f)
pool.map(f, open_connections=open_connections)
finally:
self._r()
......@@ -548,7 +561,7 @@ class DB(object):
result.open(transaction_manager, mvcc, synch)
# A good time to do some cache cleanup.
self._connectionMap(lambda c: c.cacheGC())
self._connectionMap(lambda c: c.cacheGC(), open_connections=False)
return result
......
......@@ -51,6 +51,9 @@ class RegularObject(Persistent):
init = classmethod(init)
class PersistentObject(Persistent):
pass
class CacheTests:
def test_cache(self):
......@@ -204,6 +207,35 @@ class CacheTests:
4
"""
def test_gc_on_open_connections(self):
r"""Test that automatic GC is not applied to open connections.
This test (and the corresponding fix) was introduced because of bug
report 113923.
We start with a persistent object and add a list attribute::
>>> db = databaseFromString("<zodb>\n"
... "cache-size 0\n"
... "<mappingstorage/>\n"
... "</zodb>")
>>> cn1 = db.open()
>>> r = cn1.root()
>>> r['ob'] = PersistentObject()
>>> r['ob'].l = []
>>> transaction.commit()
Now, let's modify the object in a way that doesn't get noticed. Then,
we open another connection which triggers automatic garbage
connection. After that, the object should not have been ghostified::
>>> r['ob'].l.append(1)
>>> cn2 = db.open()
>>> r['ob'].l
[1]
"""
def test_suite():
return doctest.DocTestSuite()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment