- Description - Landing a Syncronous Event System
- PLIP - 12
- Proposer - Alan Runyan
- Seconder - Sidnei or Kapil
- Status - Contemplation
EventObject? - the encapsulated Event object which holds a reference to the object which was modified, the context in which the object was modified. The EventObject? implements an Interface which allows Listeners to differentiate what sorts of Events they want to be notified.
Event Listener - A python callable that is registered to process Event's that specify an Interface. This could be a Script (Python), External Method or method on a CMFTool?.
Interface - Interface Wiki at zope.org
We will need to create a separate PloneEvents? which is a default policy for Events. This will come with a set of Interfaces, for instance: ToolModifiedEvent?, ToolCreationEvent?, ProductInstallationEvent?, ContentModifiedEvent?. A zope package of Interfaces that can be used throughout Plone to guarantee other product developers will re-use the same Events with their tools and content types.
In Plone and CMF it becomes difficult to easily integrate custom
behavior without modifying (intrusively) software. Whether this means
customizing a script or creating a subclass to override a method such
as manage_afterAdd (OFS.ObjectManager?) or createObject (CMFPlone?/skins/plone_scripts).
We need a way to expose most commonly used extension points in Plone to notify the
system as a whole when specific methods are invoked. The extensions points are typically
Points of Interest for customizers of Plone. An example would be when someone registers
with Plone; to customize this behavior you must subclass and override methods on the
Create Content and Service/Tool Events.
Base Zope Events: IPermissionsModify? (changing the Permissions through the ZMI), IObjectAdd? (object is called through the ZMI and added), IObjectRemoved? (object is removed through the ZMI). IOFSImportEvent? (someone imports data through the web, after its successful), IOFSExportEvent? (someone exports an object through the web).
We should come with core services (without have tons of interfaces) that allow programmers
to easily register and catch those events. But some aspects in CMF/Plone are fairly course
grain like DublinCore? modification. That would be a IContentModify? event but should probably
allow for people to specify they want to catch specifically only
metadata change events.
Events will only be generated inside of folders that support Events. I believe we should make it clear that OFS.Folder and CMFCore?.PortalFolder? will not support events. We should not try to monkey with them. Basically if you have a Plone Site (root PortalObject?), and PloneFolders? or ArchetypeFolders? (which should probably merge with the PloneBaseFolder?) then your system should work with all Events. Some of the API calls override ObjectMananger? calls.
Nothing is allowed to be committed until the Event is processed. Since this is a syncronous framework there should be no commmits before the Events are published. This is an example I could think of: I do not want anyone to create (Script) Pythons in the systems (even Managers) besides the owner. When a Script Python is called a IObjectAdd? event is fired, the processor could look at the person creating it and if it were not the owner of the system (say another manager) it could abort the creation. This is an abuse but allows Events to set policies very easily.
- Content creation:
- On portal_workflow.notifyCreated (the defacto standard hook point for content creation) after the object is created and has gone through all of its pre/post TTW script changes. An event should be raised, IObjectCreated?
- Content modification
- modification is tricky. I think of Modification in the sense of: content worked editing
an existing piece of content through the Plone interface. This could be properties or
editform(s). I do not think of Security modification as Content modification and I think this is ok.
- modification is tricky. I think of Modification in the sense of: content worked editing an existing piece of content through the Plone interface. This could be properties or the
- Content removal
- requires us to hook the OFS.ObjectManager? _delObject method. I do not believe manage_beforeDelete is guarantee'd to be called. Also hooked _delObject is dangerous. We need to understand the implications.
- Content events
- It should be possible for people to create their own content events. It is pretty simple: they create a Interface that inherients from IContentEvent?. Register it. And in their content object they get a hold of the Event serivce and publish the object with their customized Interface.
- Tool creation
- Services during adding may want to notify the system. For instance when CMFLinkChecker? is installed by the system an Event should be raised after addTool is called. NOTE: This requires fiddling with addTool unless the factory method can easily be changed.
- Tool changes
- When you modify the SkinsTool? path for instance. This would publish a IServiceModify? with the SkinTool? as an instance. One problem (how do you know what specifically changed without a specific interface?). i.e. How do I know what skinpaths have changed. Do I need to go back into the history of the zodb for that object and introspect its properties and compare them?
- Tool removal
- When _delObject is called on a folder with a tool it should raise an IServiceRemove? event. With the object that is being deleted. If an exception is raised the removal action would fail.
- Write examples of Tool Events, Content Events and how to make a 3rd Party Event.
- Modify existing PloneTools? to raise Events.
- Incorporate (fork) cvs.zope.org/Products/Event and EventListenerTool? (similiar to what Nuxeo has done in their CVS). We need to be conscious of submitting diff's of our changes back to Zope Corp Product Maintainers.
- PloneEvents? package
- Unit Tests of Event interaction
If we are not conservative in our implementation it could be possible to adversely affect performance of Plone. This could happen if excessive amounts of Events are triggered in a system that depend on each other.
The Zope Corp. Event service (cvs.zope.org/Products/Event) written by ChrisM? is syncronous. The downside about this approach is that when an Event is triggered it will be sent to the EventService?, which will in turn propogate the Event to registered EventListeners?. After the Event is finished processing execution can continue. During this processing the thread that is executing this Event will block. The upside to this approach is the simplicity, the 'transaction'-awareness if something borks during the Event processing everything will be rolled back, and
We are adding new software to Plone. This introduces interactions between components that may have been developed in isolation and could have unknown side-effects. A good example of this is something that
Event Service uses Persistent ObjectReferences? which could cause problems if you are processing Events across mounted storages. Let Kapil explain this part.
How Event processors and Events will work in the same execution stack with other products needs to be tested. We should probably break the Events up and let people enable levels of events. The first cut of this should probably focus on simple content/tool events. Probably no Zope events. But we should make it easy for people to turn this on.