Re: [Zope-CMF] Zope 3 events from workflow
Chris Withers wrote: > > Martin Aspeli wrote: >> To subscribe only to particular transitions, you would need for each >> transition object to provide a specific interface. > > Unless you could leverage the same kind of thing that makes named > adapters work... > Like the code I proposed? You are still then hardcoding (probably in ZCML) a relationship between event handlers and transition names (which are editable TTW), of course. >> zope.event?), it registers a general subscriber for IObjectEvent and then >> redispatches for multi-subscribers based on (obj, event), i.e. you >> register >> a handler for the object type and for the event type. > > I actually don't like this pattern, it seems needlessly inefficient. Why > not just set the right damned event going from the start? ;-) > It's only one layer of indirection, probably equivalent to a fast search (I assume the adapter registry uses trees) and a function call. There is a single implementation of this for any IObjectEvent, in fact, so since the workflow events are IObjectEvents, you'll get redispatch for free (this was intentional). If you want named redispatch, you'll need to make your own redispatcher - but that's preciely the point. No generic code could know that it's event.transition_name or whatever that is the name to redispatch upon. :) >> We could do the same for a transition event, e.g. re-dispatching based on >> object type, workflow type and/or transition type. > > Sounds like it would fit the idiom, even if I don't like it... > Think of it as framework code you don't have to see or worry about if it were written once. But again, there is no per-transition interface (all transition definition objects are of the same class, just with different names), so redispatch on interface would be tricky. > Yeah, decorators suck when abused and zcml just sucks ;-) > So use zope.component.provideAdapter/provideHandler. Martin -- View this message in context: http://www.nabble.com/Zope-3-events-from-workflow-tf2882759.html#a8141431 Sent from the Zope - CMF list2 mailing list archive at Nabble.com. ___ Zope-CMF maillist - Zope-CMF@lists.zope.org http://mail.zope.org/mailman/listinfo/zope-cmf See http://collector.zope.org/CMF for bug reports and feature requests
Re: [Zope-CMF] Zope 3 events from workflow
Martin Aspeli wrote: To subscribe only to particular transitions, you would need for each transition object to provide a specific interface. Unless you could leverage the same kind of thing that makes named adapters work... zope.event?), it registers a general subscriber for IObjectEvent and then redispatches for multi-subscribers based on (obj, event), i.e. you register a handler for the object type and for the event type. I actually don't like this pattern, it seems needlessly inefficient. Why not just set the right damned event going from the start? ;-) We could do the same for a transition event, e.g. re-dispatching based on object type, workflow type and/or transition type. Sounds like it would fit the idiom, even if I don't like it... However, in DCWorkflow, transitions are all of the same type, just with different ids, and in WorkflowTool, actions (of which DCWorkflow transitions are one common type) are also identified by a string only. See my comment about named thingies above, although this is largely hand waving on my part... It would be possible to define some kind of re-dispatch that used named adapters, but even though subscribers are just adapter factories under the hood (you'll see the slightly odd syntax of a loop that just retrieves all possible adapters from the component registry, doing nothing with the return values, because the event subscriber registry is using the same mechanism as the adapter factory registry, but the "factory" that is called normally does the event work), I don't think there's any natural syntax for registering named subscribers. You *could* do this though: @zope.component.adapter(Interface, IWorkflowTransitionEvent) def dispatch_transitions(obj, event): transition = event.transition.id factory = getMultiAdapter((obj, event), provides=INamedTransitionSubscriber, name=transition) - which would be generic and only be needed once. and then for each transition: @zope.component.implementer(INamedTransitionSubscriber) @zope.component.adapter(IMyObject, IWorkflowTransitionEvent) def react_to_published(obj, event): ... and in ZCML: I'm not sure this is any easier or less hacky than doing the subscriber like: @zope.component.adapter(Interface, IWorkflowTransitionEvent) def dispatch_transitions(obj, event): transition = event.transition.id if transition == 'publish': ... Yeah, decorators suck when abused and zcml just sucks ;-) *sigh* Chris -- Simplistix - Content Management, Zope & Python Consulting - http://www.simplistix.co.uk ___ Zope-CMF maillist - Zope-CMF@lists.zope.org http://mail.zope.org/mailman/listinfo/zope-cmf See http://collector.zope.org/CMF for bug reports and feature requests
Re: [Zope-CMF] Zope 3 events from workflow
Chris Withers wrote: > > Hi All, > > Martin Aspeli wrote: >> class IWorkflowEvent(IObjectEvent): >> """A workflow related event >> """ >> >> wf_name = TextLine(title=u"The name of the workflow this event is >> part of") >> >> transition = TextLine(title=u"The name of the transition taking >> place") >> >> state_before = TextLine(title=u"The object's state before the >> transition") >> >> state_after = TextLine(title=u"The object's state after the >> transition") > > I know I'm very late on this (sorry for taking a christmas vacation ;-) > but how would I go about subcribing to a particular transition of a > particular workflow? > > This feels like the most common case for me, but it would seem that if > you want to do that with the current patch, you'd have to have a generic > subscriber that then if/then/else'd its way to only doing the right > thing for the right workflow and the right transition. > > I thought avoiding that kind of if/then/else'ing was what event > subscribers were all about. > > Hopefully I'm just missing something, could someone enlighten me? > (and by enlighten, I don't mean anything involving automotive fuel and > matches :-P) > We've merged now :) To subscribe only to particular transitions, you would need for each transition object to provide a specific interface. If you look at the way the object event re-dispatch happens in zope.component (or was it zope.event?), it registers a general subscriber for IObjectEvent and then redispatches for multi-subscribers based on (obj, event), i.e. you register a handler for the object type and for the event type. We could do the same for a transition event, e.g. re-dispatching based on object type, workflow type and/or transition type. However, in DCWorkflow, transitions are all of the same type, just with different ids, and in WorkflowTool, actions (of which DCWorkflow transitions are one common type) are also identified by a string only. It would be possible to define some kind of re-dispatch that used named adapters, but even though subscribers are just adapter factories under the hood (you'll see the slightly odd syntax of a loop that just retrieves all possible adapters from the component registry, doing nothing with the return values, because the event subscriber registry is using the same mechanism as the adapter factory registry, but the "factory" that is called normally does the event work), I don't think there's any natural syntax for registering named subscribers. You *could* do this though: @zope.component.adapter(Interface, IWorkflowTransitionEvent) def dispatch_transitions(obj, event): transition = event.transition.id factory = getMultiAdapter((obj, event), provides=INamedTransitionSubscriber, name=transition) - which would be generic and only be needed once. and then for each transition: @zope.component.implementer(INamedTransitionSubscriber) @zope.component.adapter(IMyObject, IWorkflowTransitionEvent) def react_to_published(obj, event): ... and in ZCML: I'm not sure this is any easier or less hacky than doing the subscriber like: @zope.component.adapter(Interface, IWorkflowTransitionEvent) def dispatch_transitions(obj, event): transition = event.transition.id if transition == 'publish': ... Martin -- View this message in context: http://www.nabble.com/Zope-3-events-from-workflow-tf2882759.html#a8126055 Sent from the Zope - CMF list2 mailing list archive at Nabble.com. ___ Zope-CMF maillist - Zope-CMF@lists.zope.org http://mail.zope.org/mailman/listinfo/zope-cmf See http://collector.zope.org/CMF for bug reports and feature requests
Re: [Zope-CMF] Zope 3 events from workflow
Hi All, Martin Aspeli wrote: class IWorkflowEvent(IObjectEvent): """A workflow related event """ wf_name = TextLine(title=u"The name of the workflow this event is part of") transition = TextLine(title=u"The name of the transition taking place") state_before = TextLine(title=u"The object's state before the transition") state_after = TextLine(title=u"The object's state after the transition") I know I'm very late on this (sorry for taking a christmas vacation ;-) but how would I go about subcribing to a particular transition of a particular workflow? This feels like the most common case for me, but it would seem that if you want to do that with the current patch, you'd have to have a generic subscriber that then if/then/else'd its way to only doing the right thing for the right workflow and the right transition. I thought avoiding that kind of if/then/else'ing was what event subscribers were all about. Hopefully I'm just missing something, could someone enlighten me? (and by enlighten, I don't mean anything involving automotive fuel and matches :-P) cheers, Chris -- Simplistix - Content Management, Zope & Python Consulting - http://www.simplistix.co.uk ___ Zope-CMF maillist - Zope-CMF@lists.zope.org http://mail.zope.org/mailman/listinfo/zope-cmf See http://collector.zope.org/CMF for bug reports and feature requests
Re: [Zope-CMF] Zope 3 events from workflow
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Am I right in thinking that DCWorkflow does not send any Zope 3 events? I'm not terribly familiar with that code, but some grepping suggests so. Do you agree this would be useful? (I've got a pretty strong need for it for Plone 3, i.e. CMF 2.1 - I'm sure we can work around it in Plone, but I'd rather do it properly) It is definitely useful in the general migration towards more event- based processing. I'm not quite sure where the best place to execute the event is. One option may be DCWorkflow/DCWorkflow.py, in notifyBefore() and notifySuccess(). Here, though, I get a bit confused about how to construct the wf_name and state_before/state_after parameters. I guess they're not always needed, but they seem like they'd be useful to most event handlers. Eyeballing the code seems to suggest DCWorkflowDefinition._executeTransition as the place where both the old state and the new state are known. If events are used I'm not sure what the notify*-Methods would be used for anymore. jens -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.5 (Darwin) iD8DBQFFkixRRAx5nvEhZLIRAhABAJ0fM03/aTdY+1veRoIspYPi8HlYnwCcC5s+ xRrn5/5kVykwWZsJc8w75Ng= =8MLg -END PGP SIGNATURE- ___ Zope-CMF maillist - Zope-CMF@lists.zope.org http://mail.zope.org/mailman/listinfo/zope-cmf See http://collector.zope.org/CMF for bug reports and feature requests