On Tue, Apr 26, 2011 at 11:33:57AM +0200, Simone Carletti wrote: > > Also, in my mind a callback method should have two important properties: > > 1. it should be an optional method and you should be free to define it or > not > 2. it should not be already defined, otherwise you always have to care > about not overriding the original implementation.
Hello Simone, when I look at Wikipedia http://en.wikipedia.org/wiki/Callback_%28computer_programming%29 "In computer programming, a callback is a reference to executable code, or a piece of executable code, that is passed as an argument to other code." > You said #consume is a callback. But currently, when I wrote the following > custom participant > > class Alpha < Ruote::StorageParticipant > def consume(workitem) > # ... > super > end > end > > I must be sure to call #super, otherwise I permanently loose all the logic > defined within the original StorageParticipant#consume method. Loosing the prisoners from their logic. > Ideally, I would love to be able to write something like > > class Alpha < Ruote::StorageParticipant > def on_consume(workitem) > # ... > end > end If the #on_consume did not previously exist (and is only called if it exists). Then, granted, you have some kind of callback where the "executable code" is passed as argument (body) of the method definition. Can we really call that a callback ? There is no way to distinguish it from regular method overriding. > and have Ruote automatically invoke the method if defined. This means the > original StorageParticipant#consume should be modified to > > def consume(workitem) > # call the callback if available > on_consume(workitem) if respond_to?(:on_consume) > > doc = workitem.to_h > doc.merge!( > 'type' => 'workitems', > '_id' => to_id(doc['fei']), > 'participant_name' => doc['participant_name'], > 'wfid' => doc['fei']['wfid']) > doc['store_name'] = @store_name if @store_name > @context.storage.put(doc) > end > > This opens the door to several additional features. For instance, we can > have after/before callbacks. > > class Alpha < Ruote::StorageParticipant > def before_consume(workitem) > # ... > end > def after_consume(workitem) > # ... > end > end I guess that it brings us back to http://groups.google.com/group/openwferu-users/msg/89b3ca2dc5f07d1a I'll try to re-express my idea (maybe I will fail again) : participants are the callbacks you reference from process definitions. The engine knows how to deal with classical expressions like sequence, concurrence, cursor, etc, ... For steps themselves, he has to be fed with "external code", contained in participants. So, sorry, the "callback" I was mentioning is one level higher than the one you want. Still, I don't know if we can call a "callback" what you described. It's vanilla inheritance and overriding (with an ersatz of introspection). > It would be cool to be able to attach callbacks to the Ruote core as well, > regardless the participant you use. > Again, I'll try to formulate a more concrete proposal as soon as possible. Sounds like real callbacks. Starting from a use case is a good idea. Let's look at what ruote has in store to help you. Engine#on_error= and Engine#on_terminate= http://ruote.rubyforge.org/configuration.html#engine_on In the process definitions there are various "on_"s http://ruote.rubyforge.org/common_attributes.html#on_error http://ruote.rubyforge.org/common_attributes.html#on_cancel http://ruote.rubyforge.org/common_attributes.html#on_timeout There is also the listen expression http://ruote.rubyforge.org/exp/listen.html (note, I'm experimenting with listen and errors https://github.com/jmettraux/ruote/commit/7790c6a410f6e18a1339b67f564d44ee5ba936c1 these days) If you really need to implement something you could do : ---8<--- class WorkitemPrinter def initialize(context) @context = context @context.worker.subscribe(:all, self) if context.worker end def notify(message) p message['workitem'] if message['action'] == 'dispatch' end end # ... engine.add_service('wi_printer', nil, 'WorkitemPrinter') --->8--- (note : I'm not super happy with the add_service method, it will probably get revised soon) This sets up a 'service' that prints any workitem (the raw Hash form) that gets dispatched [to a participant]. > Also, I'll double check your code. I didn't notice you can override a single > method even if aliased. I'll try it. I am glad I double-checked and asked Ruby (1.8.7 and 1.9.2), you seemed very convinced. Best regards, -- John Mettraux - http://jmettraux.wordpress.com -- you received this message because you are subscribed to the "ruote users" group. to post : send email to [email protected] to unsubscribe : send email to [email protected] more options : http://groups.google.com/group/openwferu-users?hl=en
