Commit 219006cd authored by Jim Fulton's avatar Jim Fulton

Bugs Fixed

----------

- "activity monitor not updated for subconnections when connection
  returned to pool"

https://bugs.launchpad.net/zodb/+bug/737198
parent acab791f
......@@ -15,6 +15,7 @@
$Id$"""
import threading
import time
......@@ -24,14 +25,13 @@ class ActivityMonitor:
This simple implementation just keeps a small log in memory
and iterates over the log when getActivityAnalysis() is called.
It assumes that log entries are added in chronological sequence,
which is only guaranteed because DB.py holds a lock when calling
the closedConnection() method.
It assumes that log entries are added in chronological sequence.
"""
def __init__(self, history_length=3600):
self.history_length = history_length # Number of seconds
self.log = [] # [(time, loads, stores)]
self.trim_lock = threading.Lock()
def closedConnection(self, conn):
log = self.log
......@@ -41,6 +41,8 @@ class ActivityMonitor:
self.trim(now)
def trim(self, now):
self.trim_lock.acquire()
log = self.log
cutoff = now - self.history_length
n = 0
......@@ -49,6 +51,8 @@ class ActivityMonitor:
n = n + 1
if n:
del log[:n]
self.trim_lock.release()
def setHistoryLength(self, history_length):
self.history_length = history_length
......
......@@ -321,6 +321,10 @@ class Connection(ExportImport, object):
# get back here.
else:
self.opened = None
am = self._db._activity_monitor
if am is not None:
am.closedConnection(self)
def db(self):
"""Returns a handle to the database this connection belongs to."""
......
......@@ -491,10 +491,6 @@ class DB(object):
assert connection._db is self
connection.opened = None
am = self._activity_monitor
if am is not None:
am.closedConnection(connection)
if connection.before:
self.historical_pool.repush(connection, connection.before)
else:
......
......@@ -325,6 +325,39 @@ class UserMethodTests(unittest.TestCase):
>>> cn._Connection__onCloseCallbacks
"""
def test_close_dispatches_to_activity_monitors(self):
r"""doctest that connection close updates activity monitors
Set up a multi-database:
>>> db1 = ZODB.DB(None)
>>> db2 = ZODB.DB(None, databases=db1.databases, database_name='2',
... cache_size=10)
>>> conn1 = db1.open()
>>> conn2 = conn1.get_connection('2')
Add activity monitors to both dbs:
>>> from ZODB.ActivityMonitor import ActivityMonitor
>>> db1.setActivityMonitor(ActivityMonitor())
>>> db2.setActivityMonitor(ActivityMonitor())
Commit a transaction that affects both connections:
>>> conn1.root()[0] = conn1.root().__class__()
>>> conn2.root()[0] = conn2.root().__class__()
>>> transaction.commit()
After closing the primary connection, both monitors should be up to
date:
>>> conn1.close()
>>> len(db1.getActivityMonitor().log)
1
>>> len(db2.getActivityMonitor().log)
1
"""
def test_db(self):
r"""doctest of db() method
......
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