Re: [Zope-dev] Observer / Notification Interface Proposal
"Phillip J. Eby" wrote:
At 09:15 PM 5/24/00 -0400, Tres Seaver wrote:
Note that the scaling requirement (no blocking/long-running actions inside the notification call) is intended to support intra-request notification. A ConcreteObserver implementation which needs to perform such work (e.g., send an e-mail message, etc.) will have to extract whatever data it needs from the subject and enqueue it for processing in some other thread, by the asyncore machinery, etc.
Note as well that it would be possible to install an Observer which could "veto" the change by raising an exception (a clever ConcreteSubject might ignore such a veto, of course).
As you've probably noticed, I've been working on something similar for ZPatterns, but it's specifically oriented to the needs of Attribute/SheetProviders and Index/RuleAgents. The list of observers is effectively predefined, and the DataManager acts as a "tee" fanning out the events to the interested parties. However, subscription scope is per-transaction; the subscription takes place the first time an object hooks up with its DataManager in that transaction.
I added motivating examples to the two interfaces pages: e-mail notification and workflow state-machine transitions. Both of these involve persistent subscriptions.
I'm don't have any use case in mind for a cross-transaction "event".
Perhaps I was unclear. I was referring to maintaining the link between subject and observer for longer than a single transaction. That is, a persistent subscription.
Ah, ok -- I was planning simply to leverage the ZODB's facilities for maintaining persistent references in the DefaultObservable mix-in; more elaborate schemes would be possible (for instance to support rack-mounted observers?)
I also have hopes for a set of federated, filterable NotificationChannels (like CORBA's NotificationService) which would allow Observer-in-Zope to scale up enormously.
Hm. It seems to me that something like that would require persistent subscriptions to be of any real use, since re-subscribing on every transaction would likely be inefficient.
I apologize for the confusion -- I certainly didn't intend to convey that subscriptions were transient. As you note, that would be a less than useful "feature." -- ========================================================= Tres Seaver tseaver@digicool.com Digital Creations "Zope Dealers" http://www.zope.org
At 12:45 AM 5/25/00 -0400, Tres Seaver wrote:
Ah, ok -- I was planning simply to leverage the ZODB's facilities for maintaining persistent references in the DefaultObservable mix-in; more elaborate schemes would be possible (for instance to support rack-mounted observers?)
Actually, just using a plain reference might cause you some problems. If you don't strip off the acquisition wrapper, you'll pickle the entire acquisition tree for the subscriber, including the REQUEST and RESPONSE objects. But if you *do* strip off the wrapper, you'll call the observer without its acquisition context, causing security and possibly other problems. I would suggest using object paths, ala ZCatalog, since this fixes these problems as well as cross-database and outside-the-ZODB references. Also, it takes care of being able to pass Python-level methods as observers, since you can't pickle a direct reference to a method. The references don't have to be de-referenced unless an event actually occurs, although the high cost of de-referencing objects (even without using a path) does suggest to me that observers should at least register some kind of channel name or list of names, to prevent needless reactivations. Unless, of course, the idea is for "subjects" to not subclass Observable directly, but rather to have various "event" subobjects which are callable observables. Calling an "event" object could fire it, relaying the event to the subscribers, who would subscribe to the individual event sub-object, rather than to the main "subject" object. An interesting side-effect of this approach is that it allows one to create a subclass of "event" that can be added to any ObjectManager subclass. One could also create another subclass of event as a methoid for use in class/ZClass definitions. This subclass would store its subscription data in its parent object, allowing the event object itself to be shared across instances of the class. Still another interesting possibility is the idea that event objects could define their own calling parameters, and optionally relay those to the observers, which would allow a more interesting dataflow. In the work I've been doing on my SWARM project, workflow Plan objects have a collection of Event objects which were planned to work similarly to this, but a bit more complex. Event objects were going to have Properties, and Plans also had "Roles" (relationships to a workflow instance) which effectively were the subscribers of the events. Role objects receive all event firings, and selectively forward or transform them for their "audience" (the objects in that relationship to the workflow instance). Plans and Phases could also have Forms which were effectively input forms for the properties of an Event. Last, but not least, calling the Event object with property data would create an "event instance" object which would have methods for such things as "don't process this event further", and which would contain all the data for that firing. All that is probably overkill for this interface, but the basic idea of callable "event" sub-objects which are subscribed to by observers is I think a useful pattern to apply here.
participants (2)
-
Phillip J. Eby -
Tres Seaver