Tim Peters wrote:
[Jim Fulton]
...

From reading the source. they don't seem to fit the use case very well:

- They are registered with the TM and are called for subsequent
  transactions until they are unregistered.  This is not what we want
  here.  We want hooks to be called only if the current transaction
  commits.  We want to throw the hooks away at the end of the
  transaction.
  It's not obvious how to make this work with synchronizers.  (I suppose
  the syncronizer could save the transaction it cares about
  and unregister itself if it sees another.  This is a lot of bother.)


It's curious to consider the ways in which this fails to work:

"""
import transaction

class OneShot:
    def __init__(self, hook, *args, **kws):
        self.hook = hook
        self.args = args
        self.kws = kws
        self.txnmgr = transaction.manager
        self.txnmgr.registerSynch(self)

    def beforeCompletion(self, txn):
        self.hook(*self.args, **self.kws)

    def afterCompletion(self, txn):
        self._remove()

    def _remove(self):
        try:
            self.txnmgr.unregisterSynch(self)
        except KeyError:
            pass
"""

That is, OneShot(hook, ...) tries to work exactly the same way as your
beforeCommitHook(hook, ...).

The most obvious failure is that the hook gets called on both commit() and
abort().  I view that as a mistake in the design of beforeCompletion; there
are currently no uses of beforeCompletion() anywhere in ZODB, so I doubt it
would cause any pain to change that.  Perhaps the hook method could be
passed a string arg, 'commit' or 'abort'.

Actually it can check txn.status to decide.

A subtler failure is that "are called for subsequent transactions until they
are unregistered" isn't the full truth:  the TM holds only a weak reference
to a registered synchronizer.  If such a synchronizer becomes otherwise
unreferenced, it will vanish from the TM's weak set of registered
synchronizers, and then its methods won't get invoked at all.  If the caller
arranges to hold a strong reference to a OneShot instance until the current
transaction ends, then that part isn't an issue.

Why the weak refs? What does it help doing in the ZODB case?

Florent

--
Florent Guillaume, Nuxeo (Paris, France)   CTO, Director of R&D
+33 1 40 33 71 59   http://nuxeo.com   [EMAIL PROTECTED]
_______________________________________________
For more information about ZODB, see the ZODB Wiki:
http://www.zope.org/Wikis/ZODB/

ZODB-Dev mailing list  -  ZODB-Dev@zope.org
http://mail.zope.org/mailman/listinfo/zodb-dev

Reply via email to