[Zope-dev] Re: CopySupport, hooks, events

Geoff Davis geoff at phds.org
Mon Aug 8 15:16:18 EDT 2005


Florent, thanks for a thoughtful reply.

Maybe we should start the larger discussion in moving to an event-driven
OFS in Zope 2.8/2.9 using Five? Does Five support Z3's events (does Z3
have events yet? I have ordered Phillip's Z3 book but it has yet to arrive...)

I'm cross posting to the Plone folks to see what they think.

Geoff


On Mon, 08 Aug 2005 20:29:38 +0200, Florent Guillaume wrote:
> 
> I'd prefer names less potentially prone to clashes with existing code, 
> namely "_beforeItemMove", "_afterItemCopy", etc.
> 
> Also I tried to make a point on IRC about the recursion, and how we can 
> switch this model to an event system later, but I probably wasn't clear 
> enough. I'll try to explain better, but please bear with me :)
> 
> 
> First and foremost, I want to be able to switch from the current system 
> where each class has to implement (or inherit) _beforeItemMove so that 
> recursion applies, which would conceptually mean a base class or a mixin, to 
> a system driven by events.
> 
> Very importantly, this means that it's not _beforeItemMove's job to do the 
> recursion. Why? Because suppose I inherit from a base class that has 
> something to do before the move, and I want to add behavior to that. I'll 
> have to call the base class, let it do its recursion, and then do my 
> behavior on the current object. But suppose I inherit from two base classes 
> that both had a _beforeItemMove that did recursion ? Then the recursion has 
> to be defined and done only once, or you'd have double recursions (which 
> turns into an exponential complexity). Maybe in some kind of unique base 
> class? That's a total mess, I don't want to have to add artificial base 
> classes to my code when there's no need to. I want the recursing behavior to 
> be defined in a component (à la Zope 3), not in a base class. So the first 
> consequence of having a clean approach is that:
> 
>      It's not the hook's job to do the recursion.
> 
> So the recursion has to be done by "external" code, a component, that calls 
> all the relevant objects.
> 
> 
> Now, in the current Zope 2 system having a class with a manage_beforeDelete 
> (for instance) that just does "pass" means that the recursion is stopped. We 
> want to keep that flexibility; this is easily done by having the hook return 
> True if it wants to recurse (or to stop recursion -- we have to find what's 
> best).
> 
> 
> Here's how an event system would work (using afterItemCopy as an example):
> 
> 1. something decides to copy an object. A "beforeCopy" event is sent. Then 
> the copy is done. The an "afterCopy" event is sent.
> 
> 2. some code having the need to tidy up things after the copy has a 
> subscriber subscribed to the "afterCopy" event. For instance, there could be 
> a subscriber in CMFCatalogAware.py that indexes the new objects, calling 
> indexObject on each. A subscriber implements a policy, in this case it would 
> be "copied objects have to be indexed in their new place". Notice, it's not 
> indexObject's role to do any recursion.
> 
> 3. the subscriber may or may not want the recursion to apply. How it does 
> that is up to its implementation.
> 
> I'm stressing point 3 here because if I copy 100.000 objects I don't want 
> the default system to send 100.000 events. If I have an efficient way of 
> doing my bookkeeping, I don't want the event system do screw things up 
> behind my back. Note for instance that in CMF reindexObjectSecurity does not 
> do recursion like manage_afterAdd does, because it has optimized ways to do 
> its job without recursing using objectValues().
> 
> So I strongly believe the default event system should send a simple event on 
> copy (and I think I'll have to fight to get my way in Zope 3...). Now, if 
> something wants to recurse, it's free to do so, and maybe send more events. 
> But I want the system to be able to work without that.
> 
> Using this system, there could be a default subscriber in OFS/CopySupport.py 
> that calls _afterItemCopy on the toplevel object and then does the 
> recursion. The *subscriber* does the recursion, not _afterItemCopy.
> 
> But we're not there yet (no events in Zope 2), so instead of sending an 
> event that's caught by a subscriber that does a recursion, this can be done 
> for now by calling directly the code equivalent to the subscriber. Later 
> we'll move to the event system. (And it is my hope that we can deprecate 
> manage_beforeDelete & al. too.)
> 
> 
> So I propose:
> 
> def _beforeItemMove(dest_container, dest_path):
>      """
>      Called before an item is moved.
> 
>      dest_container may be None (since for subobjects, the
>      destination will not have been created yet).
> 
>      dest_path is a tuple containing the physical path of
>      the new container (which may not yet exist).
> 
>      Returns True if recursion should stop.
>      """
> 
> def _afterItemMove(source_container, source_path):
>      """
>      Called afer an item has been moved.
> 
>      source_container may be None (since for subobjects, the
>      source may have been moved elsewhere).
> 
>      source_path is a tuple containing the physical path of
>      the old container (which may no longer exist).
> 
>      Returns True if recursion should stop.
>      """
> 
> def _beforeItemCopy(dest_container, dest_path):
>      """
>      Called before an item is copied.
> 
>      dest_container may be None (since for subobjects, the
>      destination will not have been created yet).
> 
>      dest_path is a tuple containing the physical path of
>      the new container (which may not yet exist).
> 
>      Returns True if recursion should stop.
>      """
> 
> def _afterItemCopy(source_object):
>      """
>      Called after an item has been copied.
> 
>      source_object is the original object.
> 
>      Returns True if recursion should stop.
>      """
> 
> 
> Note, I'm not too sure about the source_container and source_object 
> parameters, they're quite expensive to maintain. I'd like to see an 
> implementation to discuss this.
> 
> 
> Florent




More information about the Zope-Dev mailing list