256 described here but higher level APIs. |
256 described here but higher level APIs. |
257 |
257 |
258 :attr:`data` is a dictionary containing shared data, used to communicate |
258 :attr:`data` is a dictionary containing shared data, used to communicate |
259 extra information between the client and the repository |
259 extra information between the client and the repository |
260 |
260 |
261 :attr:`_tx_data` is a dictionary of :class:`TransactionData` instance, one |
261 :attr:`_txs` is a dictionary of :class:`TransactionData` instance, one |
262 for each running transaction. The key is the transaction id. By default |
262 for each running transaction. The key is the transaction id. By default |
263 the transaction id is the thread name but it can be otherwise (per dbapi |
263 the transaction id is the thread name but it can be otherwise (per dbapi |
264 cursor for instance, or per thread name *from another process*). |
264 cursor for instance, or per thread name *from another process*). |
265 |
265 |
266 :attr:`__threaddata` is a thread local storage whose `txdata` attribute |
266 :attr:`__threaddata` is a thread local storage whose `txdata` attribute |
379 # shared data, used to communicate extra information between the client |
379 # shared data, used to communicate extra information between the client |
380 # and the rql server |
380 # and the rql server |
381 self.data = {} |
381 self.data = {} |
382 # i18n initialization |
382 # i18n initialization |
383 self.set_language(user.prefered_language()) |
383 self.set_language(user.prefered_language()) |
384 # internals |
384 ### internals |
385 self._tx_data = {} |
385 # Transaction of this section |
|
386 self._txs = {} |
386 # Data local to the thread |
387 # Data local to the thread |
387 self.__threaddata = threading.local() |
388 self.__threaddata = threading.local() |
388 self._threads_in_transaction = set() |
389 self._threads_in_transaction = set() |
389 self._closed = False |
390 self._closed = False |
390 self._closed_lock = threading.Lock() |
391 self._closed_lock = threading.Lock() |
391 |
392 |
392 def __unicode__(self): |
393 def __unicode__(self): |
393 return '<session %s (%s 0x%x)>' % ( |
394 return '<session %s (%s 0x%x)>' % ( |
394 unicode(self.user.login), self.id, id(self)) |
395 unicode(self.user.login), self.id, id(self)) |
395 |
396 |
396 def set_tx_data(self, txid=None): |
397 def set_tx(self, txid=None): |
397 if txid is None: |
398 if txid is None: |
398 txid = threading.currentThread().getName() |
399 txid = threading.currentThread().getName() |
399 try: |
400 try: |
400 self.__threaddata.txdata = self._tx_data[txid] |
401 self.__threaddata.txdata = self._txs[txid] |
401 except KeyError: |
402 except KeyError: |
402 rewriter = RQLRewriter(self) |
403 rewriter = RQLRewriter(self) |
403 tx = Transaction(txid, self.default_mode, rewriter) |
404 tx = Transaction(txid, self.default_mode, rewriter) |
404 self.__threaddata.txdata = self._tx_data[txid] = tx |
405 self.__threaddata.txdata = self._txs[txid] = tx |
405 |
406 |
406 @property |
407 @property |
407 def _threaddata(self): |
408 def _threaddata(self): |
408 try: |
409 try: |
409 return self.__threaddata.txdata |
410 return self.__threaddata.txdata |
410 except AttributeError: |
411 except AttributeError: |
411 self.set_tx_data() |
412 self.set_tx() |
412 return self.__threaddata.txdata |
413 return self.__threaddata.txdata |
413 |
414 |
414 def get_option_value(self, option, foreid=None): |
415 def get_option_value(self, option, foreid=None): |
415 return self.repo.get_option_value(option, foreid) |
416 return self.repo.get_option_value(option, foreid) |
416 |
417 |
1016 self._clear_tx_storage(txstore) |
1017 self._clear_tx_storage(txstore) |
1017 else: |
1018 else: |
1018 self._clear_tx_storage(txstore) |
1019 self._clear_tx_storage(txstore) |
1019 |
1020 |
1020 def _clear_thread_storage(self, txstore): |
1021 def _clear_thread_storage(self, txstore): |
1021 self._tx_data.pop(txstore.transactionid, None) |
1022 self._txs.pop(txstore.transactionid, None) |
1022 try: |
1023 try: |
1023 del self.__threaddata.txdata |
1024 del self.__threaddata.txdata |
1024 except AttributeError: |
1025 except AttributeError: |
1025 pass |
1026 pass |
1026 |
1027 |
1168 self.error('thread %s still alive after 10 seconds, will close ' |
1169 self.error('thread %s still alive after 10 seconds, will close ' |
1169 'session anyway', thread) |
1170 'session anyway', thread) |
1170 self._free_thread_cnxset(thread, cnxset, force_close=True) |
1171 self._free_thread_cnxset(thread, cnxset, force_close=True) |
1171 self.rollback() |
1172 self.rollback() |
1172 del self.__threaddata |
1173 del self.__threaddata |
1173 del self._tx_data |
1174 del self._txs |
1174 |
1175 |
1175 @property |
1176 @property |
1176 def closed(self): |
1177 def closed(self): |
1177 return not hasattr(self, '_tx_data') |
1178 return not hasattr(self, '_txs') |
1178 |
1179 |
1179 # transaction data/operations management ################################## |
1180 # transaction data/operations management ################################## |
1180 |
1181 |
1181 @property |
1182 @property |
1182 def transaction_data(self): |
1183 def transaction_data(self): |