[repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 30 Jul 2009 12:01:17 +0200
branchstable
changeset 2570 80a996bb536d
parent 2569 e48a09bda07d
child 2571 5c837feca73a
[repo session] ability to ask session to keep it's pool set even when only read queries are done, necessary at least during migration
server/migractions.py
server/session.py
--- a/server/migractions.py	Thu Jul 30 11:59:48 2009 +0200
+++ b/server/migractions.py	Thu Jul 30 12:01:17 2009 +0200
@@ -194,6 +194,7 @@
                 except (KeyboardInterrupt, EOFError):
                     print 'aborting...'
                     sys.exit(0)
+            self.session.keep_pool_mode = 'transaction'
             return self._cnx
 
     @property
--- a/server/session.py	Thu Jul 30 11:59:48 2009 +0200
+++ b/server/session.py	Thu Jul 30 12:01:17 2009 +0200
@@ -59,6 +59,7 @@
         self.timestamp = self.creation
         self.is_internal_session = False
         self.is_super_session = False
+        self.default_mode = 'read'
         # short cut to querier .execute method
         self._execute = repo.querier.execute
         # shared data, used to communicate extra information between the client
@@ -110,13 +111,33 @@
 
     # connection management ###################################################
 
+    def keep_pool_mode(self, mode):
+        """set pool_mode, e.g. how the session will keep its pool:
+
+        * if mode == 'write', the pool is freed after each ready query, but kept
+          until the transaction's end (eg commit or rollback) when a write query
+          is detected (eg INSERT/SET/DELETE queries)
+
+        * if mode == 'transaction', the pool is only freed after the
+          transaction's end
+
+        notice that a repository has a limited set of pools, and a session has to
+        wait for a free pool to run any rql query (unless it already has a pool
+        set).
+        """
+        assert mode in ('transaction', 'write')
+        if mode == 'transaction':
+            self.default_mode = 'transaction'
+        else: # mode == 'write'
+            self.default_mode = 'read'
+
     def get_mode(self):
-        return getattr(self._threaddata, 'mode', 'read')
+        return getattr(self._threaddata, 'mode', self.default_mode)
     def set_mode(self, value):
         self._threaddata.mode = value
     mode = property(get_mode, set_mode,
-                    doc='transaction mode (read/write), resetted to read on '
-                    'commit / rollback')
+                    doc='transaction mode (read/write/transaction), resetted to'
+                    ' default_mode on commit / rollback')
 
     def get_commit_state(self):
         return getattr(self._threaddata, 'commit_state', None)
@@ -145,11 +166,11 @@
             self._threads_in_transaction.add(threading.currentThread())
         return self._threaddata.pool
 
-    def reset_pool(self):
+    def reset_pool(self, ignoremode=False):
         """the session is no longer using its pool, at least for some time"""
         # pool may be none if no operation has been done since last commit
         # or rollback
-        if self.pool is not None and self.mode == 'read':
+        if self.pool is not None and (ignoremode or self.mode == 'read'):
             # even in read mode, we must release the current transaction
             pool = self.pool
             try:
@@ -165,7 +186,7 @@
         """update latest session usage timestamp and reset mode to read"""
         self.timestamp = time()
         self.local_perm_cache.clear()
-        self._threaddata.mode = 'read'
+        self._threaddata.mode = self.default_mode
 
     # shared data handling ###################################################
 
@@ -301,7 +322,7 @@
             self.pending_operations[:] = []
             self.transaction_data.clear()
             if reset_pool:
-                self.reset_pool()
+                self.reset_pool(ignoremode=True)
 
     def rollback(self, reset_pool=True):
         """rollback the current session's transaction"""
@@ -326,7 +347,7 @@
             self.pending_operations[:] = []
             self.transaction_data.clear()
             if reset_pool:
-                self.reset_pool()
+                self.reset_pool(ignoremode=True)
 
     def close(self):
         """do not close pool on session close, since they are shared now"""