Commit 28e7b2bb authored by Christian Theune's avatar Christian Theune

- Fixed bug 113932 by changing automatic garbage collection to only work on

   closed connections.
parent c3655ce6
......@@ -10,6 +10,10 @@ General
will be removed in ZODB 3.9. (They have been widely recognized as
deprecated for quite a while.)
- 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.)
ZEO
---
......
......@@ -160,9 +160,17 @@ class _ConnectionPool(object):
assert result in self.all
return result
def map(self, f):
"""For every live connection c, invoke f(c)."""
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
......@@ -360,12 +368,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()
......@@ -608,7 +621,7 @@ class DB(object):
result.open(transaction_manager)
# 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