[Florent Guillaume]
> FYI in CPS we use a simple backport of the before commit hook to ZODB
> 3.2:
> For now we use it to delay indexing of some objects to the end of the
> transaction (to avoid indexing twice the same object for instance):
> To index something, code just has to do:
> get_indexation_manager().push(ob)
> In get_indexation_manager() I have to check if there is already a
> registered IndexationManager hook with the transaction. I currently use a
> hack, but what I'd need is a way to query the registered hooks. What do
> people think of adding something like:
> def getBeforeCommitHooksImplementing(self, class_):
>     """Get the registered beforeCommit hooks subclassing class_."""
>     return [(hook, args, kws) for hook, args, kws in self._before_commit
>             if isintance(hook, class_)]
> (Interfaces could probably be a better choice than classes.) Or is it
> overengineering ? Maybe just a getBeforeCommitHooks that returns
> self._before_commit ?

Primarily I think that building 90% of an app's logic on beforeCommitHook()
may be a mistake <wink>.

That said, in general I never object to methods that reveal info other
methods set.  Building a filter into it too is indeed overkill, and actually
gets in the way for some use cases; a caller can surely filter on class, or
interface, or whatever else they like, with ease.  If your specific app
always filters on class, fine, write a tiny three-line function on top of
getBeforeCommitHooks() to do so.

Returning a list is dangerous, because it leaves transactions vulnerable to
unintended mutation, and constrains implementations forever (note that
there's _already_ a TODO in this code to switch ._before_commit to
collections.deque when Python 2.4 can be assumed).  While I don't know of an
official-ish Zope interface for this, Python's concept of "iterable object"
seems a perfect fit here to me.  Like so:

def getBeforeCommitHooks(self):
    """Return iterable producing the registered beforeCommit hooks.

    A triple (hook, args, kws) is produced for each registered hook.
    The hooks are produced in the order in which they were registered.
    return iter(self._before_commit)

Since the existing interface already promises ordering guarantees on these
hooks, I think it's a good idea to reveal that order via this method too.

Note that Zope 2.8b1 was already released (yesterday) with a ZODB 3.4 alpha,
so strictly speaking no new features should be added to ZODB 3.4.  But if
you can slam code and tests for this in quickly, I'll look the other way (I
think adding a straightforward new method is about as harmless as can be).
Just don't let Jim notice you're doing it <wink>. 

For more information about ZODB, see the ZODB Wiki:

ZODB-Dev mailing list  -  ZODB-Dev@zope.org

Reply via email to