server/session.py
branchstable
changeset 2570 80a996bb536d
parent 2319 654decb099e3
child 2589 92f2bc945261
equal deleted inserted replaced
2569:e48a09bda07d 2570:80a996bb536d
    57         self.cnxtype = cnxprops.cnxtype
    57         self.cnxtype = cnxprops.cnxtype
    58         self.creation = time()
    58         self.creation = time()
    59         self.timestamp = self.creation
    59         self.timestamp = self.creation
    60         self.is_internal_session = False
    60         self.is_internal_session = False
    61         self.is_super_session = False
    61         self.is_super_session = False
       
    62         self.default_mode = 'read'
    62         # short cut to querier .execute method
    63         # short cut to querier .execute method
    63         self._execute = repo.querier.execute
    64         self._execute = repo.querier.execute
    64         # shared data, used to communicate extra information between the client
    65         # shared data, used to communicate extra information between the client
    65         # and the rql server
    66         # and the rql server
    66         self.data = {}
    67         self.data = {}
   108         assert prop == 'lang' # this is the only one changeable property for now
   109         assert prop == 'lang' # this is the only one changeable property for now
   109         self.set_language(value)
   110         self.set_language(value)
   110 
   111 
   111     # connection management ###################################################
   112     # connection management ###################################################
   112 
   113 
       
   114     def keep_pool_mode(self, mode):
       
   115         """set pool_mode, e.g. how the session will keep its pool:
       
   116 
       
   117         * if mode == 'write', the pool is freed after each ready query, but kept
       
   118           until the transaction's end (eg commit or rollback) when a write query
       
   119           is detected (eg INSERT/SET/DELETE queries)
       
   120 
       
   121         * if mode == 'transaction', the pool is only freed after the
       
   122           transaction's end
       
   123 
       
   124         notice that a repository has a limited set of pools, and a session has to
       
   125         wait for a free pool to run any rql query (unless it already has a pool
       
   126         set).
       
   127         """
       
   128         assert mode in ('transaction', 'write')
       
   129         if mode == 'transaction':
       
   130             self.default_mode = 'transaction'
       
   131         else: # mode == 'write'
       
   132             self.default_mode = 'read'
       
   133 
   113     def get_mode(self):
   134     def get_mode(self):
   114         return getattr(self._threaddata, 'mode', 'read')
   135         return getattr(self._threaddata, 'mode', self.default_mode)
   115     def set_mode(self, value):
   136     def set_mode(self, value):
   116         self._threaddata.mode = value
   137         self._threaddata.mode = value
   117     mode = property(get_mode, set_mode,
   138     mode = property(get_mode, set_mode,
   118                     doc='transaction mode (read/write), resetted to read on '
   139                     doc='transaction mode (read/write/transaction), resetted to'
   119                     'commit / rollback')
   140                     ' default_mode on commit / rollback')
   120 
   141 
   121     def get_commit_state(self):
   142     def get_commit_state(self):
   122         return getattr(self._threaddata, 'commit_state', None)
   143         return getattr(self._threaddata, 'commit_state', None)
   123     def set_commit_state(self, value):
   144     def set_commit_state(self, value):
   124         self._threaddata.commit_state = value
   145         self._threaddata.commit_state = value
   143                 self.repo._free_pool(pool)
   164                 self.repo._free_pool(pool)
   144                 raise
   165                 raise
   145             self._threads_in_transaction.add(threading.currentThread())
   166             self._threads_in_transaction.add(threading.currentThread())
   146         return self._threaddata.pool
   167         return self._threaddata.pool
   147 
   168 
   148     def reset_pool(self):
   169     def reset_pool(self, ignoremode=False):
   149         """the session is no longer using its pool, at least for some time"""
   170         """the session is no longer using its pool, at least for some time"""
   150         # pool may be none if no operation has been done since last commit
   171         # pool may be none if no operation has been done since last commit
   151         # or rollback
   172         # or rollback
   152         if self.pool is not None and self.mode == 'read':
   173         if self.pool is not None and (ignoremode or self.mode == 'read'):
   153             # even in read mode, we must release the current transaction
   174             # even in read mode, we must release the current transaction
   154             pool = self.pool
   175             pool = self.pool
   155             try:
   176             try:
   156                 self._threads_in_transaction.remove(threading.currentThread())
   177                 self._threads_in_transaction.remove(threading.currentThread())
   157             except KeyError:
   178             except KeyError:
   163 
   184 
   164     def _touch(self):
   185     def _touch(self):
   165         """update latest session usage timestamp and reset mode to read"""
   186         """update latest session usage timestamp and reset mode to read"""
   166         self.timestamp = time()
   187         self.timestamp = time()
   167         self.local_perm_cache.clear()
   188         self.local_perm_cache.clear()
   168         self._threaddata.mode = 'read'
   189         self._threaddata.mode = self.default_mode
   169 
   190 
   170     # shared data handling ###################################################
   191     # shared data handling ###################################################
   171 
   192 
   172     def get_shared_data(self, key, default=None, pop=False):
   193     def get_shared_data(self, key, default=None, pop=False):
   173         """return value associated to `key` in session data"""
   194         """return value associated to `key` in session data"""
   299             self._touch()
   320             self._touch()
   300             self.commit_state = None
   321             self.commit_state = None
   301             self.pending_operations[:] = []
   322             self.pending_operations[:] = []
   302             self.transaction_data.clear()
   323             self.transaction_data.clear()
   303             if reset_pool:
   324             if reset_pool:
   304                 self.reset_pool()
   325                 self.reset_pool(ignoremode=True)
   305 
   326 
   306     def rollback(self, reset_pool=True):
   327     def rollback(self, reset_pool=True):
   307         """rollback the current session's transaction"""
   328         """rollback the current session's transaction"""
   308         if self.pool is None:
   329         if self.pool is None:
   309             assert not self.pending_operations
   330             assert not self.pending_operations
   324         finally:
   345         finally:
   325             self._touch()
   346             self._touch()
   326             self.pending_operations[:] = []
   347             self.pending_operations[:] = []
   327             self.transaction_data.clear()
   348             self.transaction_data.clear()
   328             if reset_pool:
   349             if reset_pool:
   329                 self.reset_pool()
   350                 self.reset_pool(ignoremode=True)
   330 
   351 
   331     def close(self):
   352     def close(self):
   332         """do not close pool on session close, since they are shared now"""
   353         """do not close pool on session close, since they are shared now"""
   333         self._closed = True
   354         self._closed = True
   334         # copy since _threads_in_transaction maybe modified while waiting
   355         # copy since _threads_in_transaction maybe modified while waiting