[Zodb-checkins] SVN: ZODB/branches/tim-simpler_connection/src/ZODB/DB.py Cleanups; better comments.

Tim Peters tim.one at comcast.net
Tue Oct 26 12:32:32 EDT 2004


Log message for revision 28252:
  Cleanups; better comments.
  
  Changed the behavior of _ConnectionPool.pop(), to return
  None when no connections are available.
  

Changed:
  U   ZODB/branches/tim-simpler_connection/src/ZODB/DB.py

-=-
Modified: ZODB/branches/tim-simpler_connection/src/ZODB/DB.py
===================================================================
--- ZODB/branches/tim-simpler_connection/src/ZODB/DB.py	2004-10-26 15:54:56 UTC (rev 28251)
+++ ZODB/branches/tim-simpler_connection/src/ZODB/DB.py	2004-10-26 16:32:32 UTC (rev 28252)
@@ -37,7 +37,7 @@
 class _ConnectionPool(object):
     """Manage a pool of connections.
 
-    CAUTION:  All methods should be called under the protection of a lock.
+    CAUTION:  Methods should be called under the protection of a lock.
     This class does no locking of its own.
 
     There's no limit on the number of connections this can keep track of,
@@ -56,7 +56,8 @@
     reference to it thereafter.  It's not necessary to inform the pool
     if the connection goes away.  A connection handed out by pop() counts
     against pool_size only so long as it exists, and provided it isn't
-    repush()'ed.
+    repush()'ed.  A weak reference is retained so that DB methods like
+    connectionDebugInfo() can still gather statistics.
     """
 
     def __init__(self, pool_size):
@@ -64,16 +65,21 @@
         self.pool_size = pool_size
 
         # A weak set of all connections we've seen.  A connection vanishes
-        # from this set if get() hands it out, it's not reregistered via
+        # from this set if pop() hands it out, it's not reregistered via
         # repush(), and it becomes unreachable.
         self.all = WeakSet()
 
         # A stack of connections available to hand out.  This is a subset
         # of self.all.  push() and repush() add to this, and may remove
         # the oldest available connections if the pool is too large.
-        # get() pops this stack.
+        # pop() pops this stack.
+        # In Python 2.4, a collections.deque would make more sense than
+        # a list (we push only "on the right", but may pop from both ends).
         self.available = []
 
+    # Change our belief about the expected maximum # of live connections.
+    # If the pool_size is smaller than the current value, this may discard
+    # the oldest available connections.
     def set_pool_size(self, pool_size):
         self.pool_size = pool_size + 1  # _reduce_size shoots for < pool_size
         self._reduce_size()
@@ -102,25 +108,24 @@
         self.available.append(c)
 
     # Throw away the oldest available connections until we're under our
-    # target size.  It may not be possible be achieve this.
+    # target size.  It may not be possible to achieve this.
     def _reduce_size(self):
         while self.available and len(self.all) >= self.pool_size:
             c = self.available.pop(0)
             self.all.remove(c)
 
-    # The number of available connections.
-    def num_available(self):
-        return len(self.available)
-
-    # Pop an available connection and return it.  A caller must ensurue
-    # that num_available() > 0 before calling pop(), and if it's not,
-    # create a connection and register it via push() first.
+    # Pop an available connection and return it, or return None if none are
+    # available.  In the latter case, the caller should create a new
+    # connection, register it via push(), and call pop() again.  The
+    # caller is responsible for serializing this sequence.
     def pop(self):
-        # Leave it in self.all, so we can still get at it for statistics
-        # while it's alive.
-        c = self.available.pop()
-        assert c in self.all
-        return c
+        result = None
+        if self.available:
+            result = self.available.pop()
+            # Leave it in self.all, so we can still get at it for statistics
+            # while it's alive.
+            assert result in self.all
+        return result
 
     # Return a list of all connections we currently know about.
     def all_as_list(self):
@@ -249,6 +254,7 @@
         if hasattr(storage, 'undoInfo'):
             self.undoInfo = storage.undoInfo
 
+    # This is called by Connection.close().
     def _closeConnection(self, connection):
         """Return a connection to the pool.
 
@@ -280,11 +286,11 @@
         finally:
             self._r()
 
-    # Call f(c) for all connections in all pools in all versions.
+    # Call f(c) for all connections c in all pools in all versions.
     def _connectionMap(self, f):
         self._a()
         try:
-            for pool in self._pools.itervalues():
+            for pool in self._pools.values():
                 for c in pool.all_as_list():
                     f(c)
         finally:
@@ -362,7 +368,7 @@
         self._connectionMap(lambda c: c._cache.full_sweep())
 
     def cacheLastGCTime(self):
-        m=[0]
+        m = [0]
         def f(con, m=m):
             t = con._cache.cache_last_gc_time
             if t > m[0]:
@@ -375,7 +381,7 @@
         self._connectionMap(lambda c: c._cache.minimize())
 
     def cacheSize(self):
-        m=[0]
+        m = [0]
         def f(con, m=m):
             m[0] += con._cache.cache_non_ghost_count
 
@@ -522,7 +528,8 @@
                 self._pools[version] = pool = _ConnectionPool(size)
 
             # result <- a connection
-            if pool.num_available() == 0:
+            result = pool.pop()
+            if result is None:
                 if version:
                     cache = self._version_cache_size
                 else:
@@ -530,7 +537,8 @@
                 c = self.klass(version=version, cache_size=cache,
                                mvcc=mvcc, txn_mgr=txn_mgr)
                 pool.push(c)
-            result = pool.pop()
+                result = pool.pop()
+            assert result is not None
 
             # Tell the connection it belongs to self.
             result._setDB(self, mvcc=mvcc, txn_mgr=txn_mgr, synch=synch)



More information about the Zodb-checkins mailing list