[z3-checkins] r23429 - in z3/sqlos/trunk/src/sqlos: . tests
jinty at codespeak.net
jinty at codespeak.net
Thu Feb 16 23:50:33 CET 2006
Author: jinty
Date: Thu Feb 16 23:50:02 2006
New Revision: 23429
Modified:
z3/sqlos/trunk/src/sqlos/configure.zcml
z3/sqlos/trunk/src/sqlos/connection.py
z3/sqlos/trunk/src/sqlos/tests/test_doctests.py
Log:
Implement per thread caching of connections and clean the cache every time we change sites.
Modified: z3/sqlos/trunk/src/sqlos/configure.zcml
==============================================================================
--- z3/sqlos/trunk/src/sqlos/configure.zcml (original)
+++ z3/sqlos/trunk/src/sqlos/configure.zcml Thu Feb 16 23:50:02 2006
@@ -149,4 +149,15 @@
/>
</configure>
+ <subscriber
+ for="zope.app.component.interfaces.ISite
+ zope.app.publication.interfaces.IBeforeTraverseEvent"
+ handler=".connection.clearCacheSubscriber"
+ />
+
+ <subscriber
+ for="zope.app.publication.interfaces.IEndRequestEvent"
+ handler=".connection.clearCacheSubscriber"
+ />
+
</configure>
Modified: z3/sqlos/trunk/src/sqlos/connection.py
==============================================================================
--- z3/sqlos/trunk/src/sqlos/connection.py (original)
+++ z3/sqlos/trunk/src/sqlos/connection.py Thu Feb 16 23:50:02 2006
@@ -16,9 +16,53 @@
from zope.component import ComponentLookupError
from zope.app import zapi
from zope.app.rdb.interfaces import IZopeDatabaseAdapter
+from zope.thread import local
from sqlos.interfaces import IZopeSQLConnection, IConnectionName
+class ConnectionCache(local):
+ """A per thread cache for adapted connections."""
+
+ def __init__(self):
+ self.connections = {}
+
+ def clear(self):
+ self.connections.clear()
+
+ def queryConnection(self, name):
+ return self.connections.get(name, None)
+
+ def setConnection(self, name, value):
+ self.connections[name] = value
+
+conn_cache = ConnectionCache()
+
+def clearCacheSubscriber(*args):
+ """A subscriber to clear the connection cache at site boundaries.
+
+ This subscriber serves a dual purpose. Firstly it makes sure that local
+ sites will work with the cache. Secondly it ensures that the cached
+ connections are not kept around forever, allowing zope.app.rdb to
+ recover from problems such as [1].
+
+ Subscribed to BeforeTraverseEvent and EndTraverseEvent.
+
+ [1] http://mail.zope.org/pipermail/zope3-dev/2005-December/017052.html
+
+ Lets just test it a little:
+
+ >>> conn_cache.clear()
+
+ >>> conn_cache.setConnection('a', 'a1')
+ >>> conn_cache.setConnection('b', 'b2')
+ >>> conn_cache.queryConnection('a')
+ 'a1'
+ >>> clearCacheSubscriber('dummy')
+ >>> conn_cache.queryConnection('a') is None
+ True
+ """
+ conn_cache.clear()
+
class SQLObjectWarning(UserWarning):
pass
@@ -30,6 +74,7 @@
self.name = name
def __get__(self, inst, cls=None):
+ # get and cache the connection name
name = self.name
if name is None:
try:
@@ -42,15 +87,16 @@
SQLObjectWarning, 2)
return
name = ut.name
- newconn = zapi.queryUtility(IZopeDatabaseAdapter, name)
- if newconn is None:
- warnings.warn("Couldn't find a rdb connection by the "
- "name %s. Please verify your setup." % name,
- SQLObjectWarning, 3)
- try:
- return IZopeSQLConnection(newconn())
- except ComponentLookupError:
- return self
+ # try get the connection from the cache, or make a new one
+ conn = conn_cache.queryConnection(name)
+ if conn is None:
+ zda = zapi.getUtility(IZopeDatabaseAdapter, name)
+ try:
+ conn = IZopeSQLConnection(zda())
+ except ComponentLookupError:
+ return self
+ conn_cache.setConnection(name, conn)
+ return conn
def __set__(self, inst, value):
# Ignore, so we don't get overriden.
Modified: z3/sqlos/trunk/src/sqlos/tests/test_doctests.py
==============================================================================
--- z3/sqlos/trunk/src/sqlos/tests/test_doctests.py (original)
+++ z3/sqlos/trunk/src/sqlos/tests/test_doctests.py Thu Feb 16 23:50:02 2006
@@ -10,6 +10,7 @@
def test_suite():
return unittest.TestSuite([
DocTestSuite('sqlos.container', optionflags=doctest.ELLIPSIS),
+ DocTestSuite('sqlos.connection'),
DocTestSuite('sqlos._transaction'),
DocTestSuite('sqlos._sqlos')
])
More information about the z3-checkins
mailing list