]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
restored WeakValueDict for threadlocal connections + profiler test, addressing
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 22 Aug 2007 19:14:30 +0000 (19:14 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 22 Aug 2007 19:14:30 +0000 (19:14 +0000)
[ticket:754]

lib/sqlalchemy/pool.py
test/profiling/alltests.py
test/profiling/pool.py [new file with mode: 0644]

index 8802337ea774f0fd9ce8b8c94960cbeab5ca7cfa..a80502df0fe2ccc66ee654a9e62b8e9a62095ad5 100644 (file)
@@ -115,7 +115,10 @@ class Pool(object):
     def __init__(self, creator, recycle=-1, echo=None, use_threadlocal=True,
                  listeners=None):
         self.logger = logging.instance_logger(self, echoflag=echo)
-        self._threadconns = {}
+        # the WeakValueDictionary works more nicely than a regular dict
+        # of weakrefs.  the latter can pile up dead reference objects which don't
+        # get cleaned out.  WVD adds from 1-6 method calls to a checkout operation.
+        self._threadconns = weakref.WeakValueDictionary()
         self._creator = creator
         self._recycle = recycle
         self._use_threadlocal = use_threadlocal
@@ -153,10 +156,10 @@ class Pool(object):
             return _ConnectionFairy(self).checkout()
 
         try:
-            return self._threadconns[thread.get_ident()]().checkout()
+            return self._threadconns[thread.get_ident()].checkout()
         except KeyError:
             agent = _ConnectionFairy(self)
-            self._threadconns[thread.get_ident()] = weakref.ref(agent)
+            self._threadconns[thread.get_ident()] = agent
             return agent.checkout()
 
     def return_conn(self, record):
index 94f7e1fd209e1e07a6df5d47cb9f3425f194fb0d..21e1b3578e3e3081dfe8e88527f1571051888aee 100644 (file)
@@ -5,6 +5,7 @@ import unittest
 def suite():
     modules_to_test = (
         'profiling.compiler',
+        'profiling.pool',
         )
     alltests = unittest.TestSuite()
     for name in modules_to_test:
diff --git a/test/profiling/pool.py b/test/profiling/pool.py
new file mode 100644 (file)
index 0000000..f113644
--- /dev/null
@@ -0,0 +1,40 @@
+import testbase
+from sqlalchemy import *
+from testlib import *
+from sqlalchemy.pool import QueuePool
+from sqlalchemy.databases import sqlite
+
+class QueuePoolTest(AssertMixin):
+    def setUp(self):
+        global pool
+        pool = QueuePool(creator = lambda: sqlite.SQLiteDialect.dbapi().connect(':memory:'), pool_size = 3, max_overflow = -1, use_threadlocal = True)
+
+    # the WeakValueDictionary used for the pool's "threadlocal" idea adds 1-6 method calls to each of these.
+    # however its just a lot easier stability wise than dealing with a strongly referencing dict of weakrefs.
+    # [ticket:754] immediately got opened when we tried a dict of weakrefs, and though the solution there
+    # is simple, it still doesn't solve the issue of "dead" weakrefs sitting in the dict taking up space
+    
+    @profiling.profiled('pooltest_connect', call_range=(40, 45), always=True)
+    def test_first_connect(self):
+        conn = pool.connect()
+
+    def test_second_connect(self):
+        conn = pool.connect()
+        conn.close()
+
+        @profiling.profiled('pooltest_second_connect', call_range=(24, 24), always=True)
+        def go():
+            conn2 = pool.connect()
+            return conn2
+        c2 = go()
+        
+    def test_second_samethread_connect(self):
+        conn = pool.connect()
+        
+        @profiling.profiled('pooltest_samethread_connect', call_range=(4, 4), always=True)
+        def go():
+            return pool.connect()
+        c2 = go()
+            
+if __name__ == '__main__':
+    testbase.main()