[ZODB-Dev] Re: [Zope-dev] Re: post publishing hook

Florent Guillaume fg at nuxeo.com
Mon Apr 4 14:41:50 EDT 2005


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   fg at nuxeo.com


More information about the ZODB-Dev mailing list