server/session.py
changeset 2589 92f2bc945261
parent 2466 c4ccfd38a542
parent 2570 80a996bb536d
child 2603 e47d63351891
equal deleted inserted replaced
2586:879912fe94e1 2589:92f2bc945261
    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"""
   306             self._touch()
   327             self._touch()
   307             self.commit_state = None
   328             self.commit_state = None
   308             self.pending_operations[:] = []
   329             self.pending_operations[:] = []
   309             self.transaction_data.clear()
   330             self.transaction_data.clear()
   310             if reset_pool:
   331             if reset_pool:
   311                 self.reset_pool()
   332                 self.reset_pool(ignoremode=True)
   312 
   333 
   313     def rollback(self, reset_pool=True):
   334     def rollback(self, reset_pool=True):
   314         """rollback the current session's transaction"""
   335         """rollback the current session's transaction"""
   315         if self.pool is None:
   336         if self.pool is None:
   316             assert not self.pending_operations
   337             assert not self.pending_operations
   331         finally:
   352         finally:
   332             self._touch()
   353             self._touch()
   333             self.pending_operations[:] = []
   354             self.pending_operations[:] = []
   334             self.transaction_data.clear()
   355             self.transaction_data.clear()
   335             if reset_pool:
   356             if reset_pool:
   336                 self.reset_pool()
   357                 self.reset_pool(ignoremode=True)
   337 
   358 
   338     def close(self):
   359     def close(self):
   339         """do not close pool on session close, since they are shared now"""
   360         """do not close pool on session close, since they are shared now"""
   340         self._closed = True
   361         self._closed = True
   341         # copy since _threads_in_transaction maybe modified while waiting
   362         # copy since _threads_in_transaction maybe modified while waiting