def test_map_w_gced_element(self): import gc from transaction.weakset import WeakSet w = WeakSet() dummy = Dummy() dummy2 = Dummy() dummy3 = [Dummy()] w.add(dummy) w.add(dummy2) w.add(dummy3[0]) _orig = w.as_weakref_list def _as_weakref_list(): # simulate race condition during iteration of list # object is collected after being iterated. result = _orig() del dummy3[:] gc.collect() return result w.as_weakref_list = _as_weakref_list def poker(x): x.poked = 1 w.map(poker) for thing in dummy, dummy2: self.assertEqual(thing.poked, 1)
def test_remove(self): w = WeakSet() dummy = Dummy() w.add(dummy) self.assertEqual(dummy in w, True) w.remove(dummy) self.assertEqual(dummy in w, False)
def test_contains(self): w = WeakSet() dummy = Dummy() w.add(dummy) self.assertEqual(dummy in w, True) dummy2 = Dummy() self.assertEqual(dummy2 in w, False)
def test_contains(self): from transaction.weakset import WeakSet w = WeakSet() dummy = Dummy() w.add(dummy) self.assertEqual(dummy in w, True) dummy2 = Dummy() self.assertEqual(dummy2 in w, False)
def test_remove(self): from transaction.weakset import WeakSet w = WeakSet() dummy = Dummy() w.add(dummy) self.assertEqual(dummy in w, True) w.remove(dummy) self.assertEqual(dummy in w, False)
def test_len(self): w = WeakSet() d1 = Dummy() d2 = Dummy() w.add(d1) w.add(d2) self.assertEqual(len(w), 2) del d1 self.assertEqual(len(w), 1)
def test_len(self): import gc from transaction.weakset import WeakSet w = WeakSet() d1 = Dummy() d2 = Dummy() w.add(d1) w.add(d2) self.assertEqual(len(w), 2) del d1 gc.collect() self.assertEqual(len(w), 1)
def test_len(self): import gc w = WeakSet() d1 = Dummy() d2 = Dummy() w.add(d1) w.add(d2) self.assertEqual(len(w), 2) del d1 gc.collect() self.assertEqual(len(w), 1)
def test_len(self): import gc from transaction.weakset import WeakSet w = WeakSet() d1 = Dummy() d2 = Dummy() w.add(d1) w.add(d2) self.assertEqual(len(w), 2) del d1 gc.collect() if not JYTHON: # The Jython GC is non deterministic self.assertEqual(len(w), 1)
def get(self): tid = thread.get_ident() txn = self._txns.get(tid) if txn is None: synchs = self._synchs.get(tid) if synchs is None: synchs = self._synchs[tid] = WeakSet() txn = self._txns[tid] = Transaction(synchs, self) return txn
class TransactionManager(object): def __init__(self): self._txn = None self._synchs = WeakSet() def begin(self): if self._txn is not None: self._txn.abort() txn = self._txn = Transaction(self._synchs, self) _new_transaction(txn, self._synchs) return txn def get(self): if self._txn is None: self._txn = Transaction(self._synchs, self) return self._txn def free(self, txn): assert txn is self._txn self._txn = None def registerSynch(self, synch): self._synchs.add(synch) def unregisterSynch(self, synch): self._synchs.remove(synch) def isDoomed(self): return self.get().isDoomed() def doom(self): return self.get().doom() def commit(self): return self.get().commit() def abort(self): return self.get().abort() def savepoint(self, optimistic=False): return self.get().savepoint(optimistic)
def begin(self): tid = thread.get_ident() txn = self._txns.get(tid) if txn is not None: txn.abort() synchs = self._synchs.get(tid) if synchs is None: synchs = self._synchs[tid] = WeakSet() txn = self._txns[tid] = Transaction(synchs, self) _new_transaction(txn, synchs) return txn
def test_as_weakref_list(self): w = WeakSet() dummy = Dummy() dummy2 = Dummy() dummy3 = Dummy() w.add(dummy) w.add(dummy2) w.add(dummy3) del dummy3 L = [x() for x in w.as_weakref_list()] self.assertEqual(L, [dummy, dummy2])
def test_map(self): w = WeakSet() dummy = Dummy() dummy2 = Dummy() dummy3 = Dummy() w.add(dummy) w.add(dummy2) w.add(dummy3) def poker(x): x.poked = 1 w.map(poker) for thing in dummy, dummy2, dummy3: self.assertEqual(thing.poked, 1)
def test_map(self): from transaction.weakset import WeakSet w = WeakSet() dummy = Dummy() dummy2 = Dummy() dummy3 = Dummy() w.add(dummy) w.add(dummy2) w.add(dummy3) def poker(x): x.poked = 1 w.map(poker) for thing in dummy, dummy2, dummy3: self.assertEqual(thing.poked, 1)
def test_as_weakref_list(self): w = WeakSet() dummy = Dummy() dummy2 = Dummy() dummy3 = Dummy() w.add(dummy) w.add(dummy2) w.add(dummy3) del dummy3 L = [x() for x in w.as_weakref_list()] # L is a list, but it does not have a guaranteed order. self.assert_(list, type(L)) self.assertEqual(set(L), set([dummy, dummy2]))
def test_as_weakref_list(self): w = WeakSet() dummy = Dummy() dummy2 = Dummy() dummy3 = Dummy() w.add(dummy) w.add(dummy2) w.add(dummy3) del dummy3 L = [x() for x in w.as_weakref_list()] # L is a list, but it does not have a guaranteed order. self.assertTrue(list, type(L)) self.assertEqual(set(L), set([dummy, dummy2]))
def __init__(self, synchronizers=None, manager=None): self.status = Status.ACTIVE # List of resource managers, e.g. MultiObjectResourceAdapters. self._resources = [] # Weak set of synchronizer objects to call. if synchronizers is None: synchronizers = WeakSet() self._synchronizers = synchronizers self._manager = manager # _adapters: Connection/_p_jar -> MultiObjectResourceAdapter[Sub] self._adapters = {} self._voted = {} # id(Connection) -> boolean, True if voted # _voted and other dictionaries use the id() of the resource # manager as a key, because we can't guess whether the actual # resource managers will be safe to use as dict keys. # The user, description, and extension attributes are accessed # directly by storages, leading underscore notwithstanding. self.extension = {} self.log = _makeLogger() self.log.debug("new transaction") # If a commit fails, the traceback is saved in _failure_traceback. # If another attempt is made to commit, TransactionFailedError is # raised, incorporating this traceback. self._failure_traceback = None # List of (hook, args, kws) tuples added by addBeforeCommitHook(). self._before_commit = [] # List of (hook, args, kws) tuples added by addAfterCommitHook(). self._after_commit = [] # List of (hook, args, kws) tuples added by addBeforeAbortHook(). self._before_abort = [] # List of (hook, args, kws) tuples added by addAfterAbortHook(). self._after_abort = []
def test_as_weakref_list(self): import gc from transaction.weakset import WeakSet w = WeakSet() dummy = Dummy() dummy2 = Dummy() dummy3 = Dummy() w.add(dummy) w.add(dummy2) w.add(dummy3) del dummy3 gc.collect() refs = w.as_weakref_list() self.assertTrue(isinstance(refs, list)) L = [x() for x in refs] # L is a list, but it does not have a guaranteed order. self.assertTrue(list, type(L)) self.assertEqual(set(L), set([dummy, dummy2]))
def test_as_weakref_list(self): import gc from transaction.weakset import WeakSet w = WeakSet() dummy = Dummy() dummy2 = Dummy() dummy3 = Dummy() w.add(dummy) w.add(dummy2) w.add(dummy3) del dummy3 gc.collect() L = [x() for x in w.as_weakref_list()] # L is a list, but it does not have a guaranteed order. self.assertTrue(list, type(L)) self.assertEqual(set(L), set([dummy, dummy2]))
class TransactionManager(object): def __init__(self, explicit=False): self.explicit = explicit self._txn = None self._synchs = WeakSet() def begin(self): """ See ITransactionManager. """ if self._txn is not None: if self.explicit: raise AlreadyInTransaction() self._txn.abort() txn = self._txn = Transaction(self._synchs, self) _new_transaction(txn, self._synchs) return txn __enter__ = lambda self: self.begin() def get(self): """ See ITransactionManager. """ if self._txn is None: if self.explicit: raise NoTransaction() self._txn = Transaction(self._synchs, self) return self._txn def free(self, txn): if txn is not self._txn: raise ValueError("Foreign transaction") self._txn = None def registerSynch(self, synch): """ See ITransactionManager. """ self._synchs.add(synch) if self._txn is not None: synch.newTransaction(self._txn) def unregisterSynch(self, synch): """ See ITransactionManager. """ self._synchs.remove(synch) def clearSynchs(self): """ See ITransactionManager. """ self._synchs.clear() def registeredSynchs(self): """ See ITransactionManager. """ return bool(self._synchs) def isDoomed(self): """ See ITransactionManager. """ return self.get().isDoomed() def doom(self): """ See ITransactionManager. """ return self.get().doom() def commit(self): """ See ITransactionManager. """ return self.get().commit() def abort(self): """ See ITransactionManager. """ return self.get().abort() def __exit__(self, t, v, tb): if v is None: self.commit() else: self.abort() def savepoint(self, optimistic=False): """ See ITransactionManager. """ return self.get().savepoint(optimistic) def attempts(self, number=3): if number <= 0: raise ValueError("number must be positive") while number: number -= 1 if number: attempt = Attempt(self) yield attempt if attempt.success: break else: yield self def _retryable(self, error_type, error): if issubclass(error_type, TransientError): return True for dm in self.get()._resources: should_retry = getattr(dm, 'should_retry', None) if (should_retry is not None) and should_retry(error): return True return False run_no_func_types = int, type(None) def run(self, func=None, tries=3): if isinstance(func, self.run_no_func_types): if func is not None: tries = func return lambda func: self.run(func, tries) if tries <= 0: raise ValueError("tries must be positive") # These are ordinarily native strings, but that's # not required. A callable class could override them # to anything, and a Python 2.7 file could have # imported `from __future__ import unicode_literals` # which gets unicode docstrings. name = func.__name__ doc = func.__doc__ name = text_(name) if name else u'' doc = text_(doc) if doc else u'' if name != u'_': if doc: doc = name + u'\n\n' + doc else: doc = name for i in range(1, tries + 1): # pragma: no branch txn = self.begin() if doc: txn.note(doc) try: result = func() txn.commit() except Exception as v: if i == tries: raise # that was our last chance retry = self._retryable(v.__class__, v) txn.abort() if not retry: raise else: return result
class TransactionManager(object): def __init__(self): self._txn = None self._synchs = WeakSet() def begin(self): if self._txn is not None: self._txn.abort() txn = self._txn = Transaction(self._synchs, self) _new_transaction(txn, self._synchs) return txn __enter__ = lambda self: self.begin() def get(self): if self._txn is None: self._txn = Transaction(self._synchs, self) return self._txn def free(self, txn): assert txn is self._txn self._txn = None def registerSynch(self, synch): self._synchs.add(synch) def unregisterSynch(self, synch): self._synchs.remove(synch) def isDoomed(self): return self.get().isDoomed() def doom(self): return self.get().doom() def commit(self): return self.get().commit() def abort(self): return self.get().abort() def __exit__(self, t, v, tb): if v is None: self.commit() else: self.abort() def savepoint(self, optimistic=False): return self.get().savepoint(optimistic) def attempts(self, number=3): assert number > 0 while number: number -= 1 if number: yield Attempt(self) else: yield self def _retryable(self, error_type, error): if issubclass(error_type, TransientError): return True for dm in self.get()._resources: should_retry = getattr(dm, 'should_retry', None) if (should_retry is not None) and should_retry(error): return True
def registerSynch(self, synch): tid = thread.get_ident() ws = self._synchs.get(tid) if ws is None: ws = self._synchs[tid] = WeakSet() ws.add(synch)
def __init__(self): self._txn = None self._synchs = WeakSet()
class TransactionManager(object): def __init__(self): self._txn = None self._synchs = WeakSet() def begin(self): """ See ITransactionManager. """ if self._txn is not None: self._txn.abort() txn = self._txn = Transaction(self._synchs, self) _new_transaction(txn, self._synchs) return txn __enter__ = lambda self: self.begin() def get(self): """ See ITransactionManager. """ if self._txn is None: self._txn = Transaction(self._synchs, self) return self._txn def free(self, txn): if txn is not self._txn: raise ValueError("Foreign transaction") self._txn = None def registerSynch(self, synch): """ See ITransactionManager. """ self._synchs.add(synch) if self._txn is not None: synch.newTransaction(self._txn) def unregisterSynch(self, synch): """ See ITransactionManager. """ self._synchs.remove(synch) def clearSynchs(self): """ See ITransactionManager. """ self._synchs.clear() def registeredSynchs(self): """ See ITransactionManager. """ return bool(self._synchs) def isDoomed(self): """ See ITransactionManager. """ return self.get().isDoomed() def doom(self): """ See ITransactionManager. """ return self.get().doom() def commit(self): """ See ITransactionManager. """ return self.get().commit() def abort(self): """ See ITransactionManager. """ return self.get().abort() def __exit__(self, t, v, tb): if v is None: self.commit() else: self.abort() def savepoint(self, optimistic=False): """ See ITransactionManager. """ return self.get().savepoint(optimistic) def attempts(self, number=3): if number <= 0: raise ValueError("number must be positive") while number: number -= 1 if number: yield Attempt(self) else: yield self def _retryable(self, error_type, error): if issubclass(error_type, TransientError): return True for dm in self.get()._resources: should_retry = getattr(dm, 'should_retry', None) if (should_retry is not None) and should_retry(error): return True
class TransactionManager(object): def __init__(self): self._txn = None self._synchs = WeakSet() def begin(self): """ See ITransactionManager. """ if self._txn is not None: self._txn.abort() txn = self._txn = Transaction(self._synchs, self) _new_transaction(txn, self._synchs) return txn __enter__ = lambda self: self.begin() def get(self): """ See ITransactionManager. """ if self._txn is None: self._txn = Transaction(self._synchs, self) return self._txn def free(self, txn): if txn is not self._txn: raise ValueError("Foreign transaction") self._txn = None def registerSynch(self, synch): """ See ITransactionManager. """ self._synchs.add(synch) if self._txn is not None: synch.newTransaction(self._txn) def unregisterSynch(self, synch): """ See ITransactionManager. """ self._synchs.remove(synch) def clearSynchs(self): """ See ITransactionManager. """ self._synchs.clear() def registeredSynchs(self): """ See ITransactionManager. """ return bool(self._synchs) def isDoomed(self): """ See ITransactionManager. """ return self.get().isDoomed() def doom(self): """ See ITransactionManager. """ return self.get().doom() def commit(self): """ See ITransactionManager. """ return self.get().commit() def abort(self): """ See ITransactionManager. """ return self.get().abort() def __exit__(self, t, v, tb): if v is None: self.commit() else: self.abort() def savepoint(self, optimistic=False): """ See ITransactionManager. """ return self.get().savepoint(optimistic) def attempts(self, number=3): if number <= 0: raise ValueError("number must be positive") while number: number -= 1 if number: attempt = Attempt(self) yield attempt if attempt.success: break else: yield self def _retryable(self, error_type, error): if issubclass(error_type, TransientError): return True for dm in self.get()._resources: should_retry = getattr(dm, 'should_retry', None) if (should_retry is not None) and should_retry(error): return True run_no_func_types = int, type(None) def run(self, func=None, tries=3): if isinstance(func, self.run_no_func_types): if func is not None: tries = func return lambda func: self.run(func, tries) if tries <= 0: raise ValueError("tries must be positive") name = func.__name__ doc = func.__doc__ if name != '_': if doc: doc = name + '\n\n' + doc else: doc = name if doc and not isinstance(doc, text_type): doc = doc.decode('utf-8') for i in range(1, tries + 1): txn = self.begin() if doc: txn.note(doc) try: result = func() txn.commit() except Exception as v: if i == tries: raise # that was our last chance retry = self._retryable(v.__class__, v) txn.abort() if not retry: raise else: return result
class TransactionManager(object): def __init__(self): self._txn = None self._synchs = WeakSet() def begin(self): """ See ITransactionManager. """ if self._txn is not None: self._txn.abort() txn = self._txn = Transaction(self._synchs, self) _new_transaction(txn, self._synchs) return txn __enter__ = lambda self: self.begin() def get(self): """ See ITransactionManager. """ if self._txn is None: self._txn = Transaction(self._synchs, self) return self._txn def free(self, txn): if txn is not self._txn: raise ValueError("Foreign transaction") self._txn = None def registerSynch(self, synch): """ See ITransactionManager. """ self._synchs.add(synch) if self._txn is not None: synch.newTransaction(self._txn) def unregisterSynch(self, synch): """ See ITransactionManager. """ self._synchs.remove(synch) def clearSynchs(self): """ See ITransactionManager. """ self._synchs.clear() def registeredSynchs(self): """ See ITransactionManager. """ return bool(self._synchs) def isDoomed(self): """ See ITransactionManager. """ return self.get().isDoomed() def doom(self): """ See ITransactionManager. """ return self.get().doom() def commit(self): """ See ITransactionManager. """ return self.get().commit() def abort(self): """ See ITransactionManager. """ return self.get().abort() def __exit__(self, t, v, tb): if v is None: self.commit() else: self.abort() def savepoint(self, optimistic=False): """ See ITransactionManager. """ return self.get().savepoint(optimistic) def attempts(self, number=3): if number <= 0: raise ValueError("number must be positive") while number: number -= 1 if number: attempt = Attempt(self) yield attempt if attempt.success: break else: yield self def _retryable(self, error_type, error): if issubclass(error_type, TransientError): return True for dm in self.get()._resources: should_retry = getattr(dm, 'should_retry', None) if (should_retry is not None) and should_retry(error): return True run_no_func_types = int, type(None) def run(self, func=None, tries=3): if isinstance(func, self.run_no_func_types): if func is not None: tries = func return lambda func: self.run(func, tries) if tries <= 0: raise ValueError("tries must be positive") name = func.__name__ doc = func.__doc__ if name != '_': if doc: doc = name + '\n\n' + doc else: doc = name if doc and not isinstance(doc, text_type): doc = doc.decode('utf-8') for i in range(1, tries + 1): # pragma: no branch txn = self.begin() if doc: txn.note(doc) try: result = func() txn.commit() except Exception as v: if i == tries: raise # that was our last chance retry = self._retryable(v.__class__, v) txn.abort() if not retry: raise else: return result
def __init__(self, explicit=False): self.explicit = explicit self._txn = None self._synchs = WeakSet()