[Zope-PTK] [Fwd: Re: [Zope-PTK] New tool proposal: portal_events]

Tres Seaver tseaver@palladion.com
Wed, 23 Aug 2000 11:22:43 -0400


*My apologies -- I neglected to CC the PTK list on this reply.*

Shane Hathaway wrote:
> 
> Tres Seaver wrote:
> >   class PortalEventSource:
> >       def register( observer ):
> >           """ Register an event sink for future notification.
> >
> >               'observer' -- must be a traversable path to an
> >                 object conforming to the PortalEventSink interface.
> >           """
> >
> >       def unregister( observer ):
> >           """ Unegister an event sink to prevent future notification.
> >
> >               'observer' -- must be a traversable path to an
> >                 object conforming to the PortalEventSink interface.
> >           """
> 
> Don't we need to add a broadcast(eventType, payload=None, **kw) method
> to PortalEventSource? Of course there are other ways to accomplish the
> same objective; the best approach is open for debate.

No, the 'portal_events' tool is both a PortalEventSource and a
PortalEventSink -- the 'notify' method of PortalEventSink is the
equivalent of the 'broadcast' you propose.

> Also, we might move register(), unregister(), and broadcast() into a
> simple base class called "EventSource" then add a minimal subclass
> called PortalEventSource.

The two PortalEventS* classes are intended to be interfaces;  we would
have a "real" class as well, which implemented both.

> >   class PortalEventSink:
> >       def notify( eventType, payload=None, **kw ):
> >           """ Process an event from an event source.
> >
> >               'eventType' -- meant to be easily tested for filtering;
> >                 may be a well-known constant, a class object, etc.
> >
> >               'payload' -- event data (or a lazy proxy therefore).
> >
> >               'kw' -- meta-data about the event, especially useful
> >                 for filtering.
> >
> >               Implementations of this interface contract to handle
> >               these notifications "quickly", without blocking.
> >           """
> 
> Minor point: Should we require eventType to be immutable, thus allowing
> it to be used as a key in a mapping?  It would also clarify the proper
> usage.

Being able to install handlers in a dictionary keyed by type would
certainly be nice;  I am currently inclined to pass class objects,
actually::

  class PortalEvent: pass

  class PortalFolderEvent( PortalEvent ): pass

  class PortalFolderAddEvent( PortalFolderEvent ): pass

  # ....

  portal_events.notify( PortalFolderAddEvent
                      , container=self.getPhysicalPath()
                      , new_id=new_id
                      )
> 
> > Here are the events I foresee flowing through 'portal_events':
> >
> >  * ObjectManagers within the portal will notify the tool when
> >    objects are added or removed (the portal_catalog will subscribe
> >    to get these).
> >
> >  * PortalContent will notify the tool when saving changes (the
> >    portal_catalog can subscribe to this one, too).
> >
> >  * The portal_registration tool will notify of newly-added members.
> 
> * workflow status changes, which would be a separate event.
> 
> * additions to the discussion attached to an object.

Excellent!

> Note that portal_events should eliminate the need for hook-like
> functions.

Yep, that was one of my motivations.

> Another point worthy of discussion is whether (and how) portal_events
> should provide event filtering (which may or may not be useful for
> scaleability.)

I think filtering would be a reasonable extension, but might
best be added by "federating" objects;  one could add an instance of
another class (e.g., PortalEventFilter) which subscribed to the
main event channel, but applied filtering based on the eventType
or keywords before passing on the notifications to its subscribers.

Tres.
-- 
=========================================================
Tres Seaver                          tseaver@digicool.com
Digital Creations   "Zope Dealers"   http://www.zope.org