[z3-checkins] r42645 - z3/sqlos/trunk/src/sqlos

kobold at codespeak.net kobold at codespeak.net
Thu May 3 21:20:03 CEST 2007


Author: kobold
Date: Thu May  3 21:20:03 2007
New Revision: 42645

Modified:
   z3/sqlos/trunk/src/sqlos/_transaction.py
   z3/sqlos/trunk/src/sqlos/connection.py
Log:
Fixed a threading issue: with high volumes, sqlos still does not scale well.
Let's try with a local cache of connection, instead of a global one, and using
a different approach at transaction boundaries: remove the object from the
cache only for the current thread.


Modified: z3/sqlos/trunk/src/sqlos/_transaction.py
==============================================================================
--- z3/sqlos/trunk/src/sqlos/_transaction.py	(original)
+++ z3/sqlos/trunk/src/sqlos/_transaction.py	Thu May  3 21:20:03 2007
@@ -21,7 +21,7 @@
 from sqlobject import SQLObjectNotFound
 
 from sqlos.interfaces import ISQLObject
-from sqlos.connection import connCache
+
 
 def beforeCommitHook(obj):
     """Called before transactions are started.
@@ -37,6 +37,7 @@
     if not obj.sqlmeta._obsolete:
         obj.sync()
 
+
 def expireSQLObject(obj):
     """Expire the SQLObject.
 
@@ -56,13 +57,10 @@
         >>> expireSQLObject(obj)
 
     """
-    # Sometimes, the object doesn't have the id: in this case, ignore it.
+    # Expire object values. The transaction has either been aborted or
+    # committed. Sometimes, the object doesn't have the id: in this case,
+    # ignore it.
     if hasattr(obj, 'id'):
-        for connection in connCache.values():
-            connection.cache.expire(obj.id, obj.__class__)
-
-        # Expire object values. The transaction has either been aborted or
-        # committed.
         obj.expire()
 
 

Modified: z3/sqlos/trunk/src/sqlos/connection.py
==============================================================================
--- z3/sqlos/trunk/src/sqlos/connection.py	(original)
+++ z3/sqlos/trunk/src/sqlos/connection.py	Thu May  3 21:20:03 2007
@@ -21,12 +21,12 @@
 """
 __metaclass__ = type
 
-import thread
 import warnings
 
 from zope.app import zapi
 from zope.component import ComponentLookupError, getUtility
 from zope.rdb.interfaces import IZopeDatabaseAdapter
+from zope.thread import local
 
 from sqlos.interfaces import IZopeSQLConnection, IConnectionName
 
@@ -68,14 +68,12 @@
 
 # Connection cache, one per thread, a-la Transaction.
 # This code was heavily based on ZODB.Transaction
-connCache = {}
+connCache = local()
 
 
 def getConnection(context, name):
     global connCache
-    tid = thread.get_ident()
-    key = (tid, name)
-    if not connCache.get(key):
+    if not hasattr(connCache, 'connection'):
         newconn = zapi.queryUtility(IZopeDatabaseAdapter, name,
                                     default=None,
                                     context=context)
@@ -85,26 +83,21 @@
             return None
         conn = IZopeSQLConnection(newconn())
         if conn.supportTransactions:
-            connCache[key] = conn.transaction()
+            connCache.connection = conn.transaction()
         else: # At least MySQL does not support transactions
-            connCache[key] = conn
+            connCache.connection = conn
 
-    return connCache[key]
+    return connCache.connection
 
 
 def releaseConnection(name):
     global connCache
-    tid = thread.get_ident()
-    key = (tid, name)
-    if connCache.has_key(key):
-        connCache[key].close()
-        del connCache[key]
+    if hasattr(connCache, 'connection'):
+        connCache.connection.close()
+        del connCache.connection
 
 
 def clearCacheSubscriber(*args):
     """A subscriber to clear the connection cache at site boundaries."""
-    tid = thread.get_ident()
-    for name in connCache.keys():
-        if name[0] != tid:
-            continue
-        connCache[name].cache.clear()
+    if hasattr(connCache, 'connection'):
+        connCache.connection.cache.clear()


More information about the z3-checkins mailing list