Executing a block of code before/after a #consume and before/after a #reply

9 views
Skip to first unread message

Simone Carletti

unread,
Mar 31, 2011, 10:57:12 AM3/31/11
to openwfe...@googlegroups.com
Hello,

in my workflow I need to use storage participants to store a workitem in CouchDB, waiting for user interaction.
The base flow is really similar to the ruote-on-rails application.
  1. a workflow is launched
  2. a workitem reach a specific storage participant and triggers the participant consume action
  3. the consume doesn't immediately reply_to_engine but wait for user interaction
  4. when the user finishes, he proceeds and the Rails application calls #reply passing given workitem
  5. Ruote continues in the workflow and the workitem is forwarded
Roughly, we can isolate two specific time-frames:
  1. when the participant receives the workitem (in)
  2. when the participant replies to the workitem (out)
What is the best way to execute a piece of code before the workitem is consumed and after the workitem is replied?

Let me provide a bit of context. Take the following workflow as example

    Ruote.process_definition :name => 'test' do
      participant :client,  :task => "signup"
      participant :client,  :task => "pay"
      participant :service, :task => "deliver"
    end

    engine.register
      participant :client,  ClientParticipant
      participant :service, ServiceParticipant
    end 

The Client participant can do several tasks. We normally use the convention to pass a :task variable to distinguish which kind of "action" should be performed.
The participants are StorageParticipant, thus the action is something in charge of the user and (in our case) handled by a Rails controller.

Because we need to prepare the user action and validate the result, we need to execute a "prepare signup" block of code before the task is executed and a "validate signup" block of code after the task is executed.

So far, we used an approach that is completely against the Ruote design and I'm trying to identify a better approach. My original idea was to use the storage participant #consume action to trigger the "before" callback and the #on_reply action to trigger the after.

Unfortunately, this approach has two problems:
  1. the #on_reply doesn't really act as an after_filter. I have no way to stop the execution in case, for example, the block returns false or raises an exception.
  2. talking about exception, we use exception to validate user input and the before/after callback. In case the task signup requires some user data and the user doesn't provide the necessary data and tries to proceed, in the "after" callback we raise a validation error and prevent the #reply to be invoked. Unfortunately, Ruote seems to catch any error and we cannot raise custom exceptions in the #consume or #on_reply because we won't be able to rescue them.
So, back to the original question: what is the best way to implement a before/after consume/reply callbacks by using the current Ruote version?

Would such kind of callback system a reasonable feature to be implemented in Ruote? In that case, we can try to implement the feature and contribute back, but I honestly would love to know if is there any change to get this feature merged before start working on it will probably be a quite time-consuming task.

Thanks!

--
Simone Carletti
Application Developer

Skype: weppos


Simone Carletti

unread,
Mar 31, 2011, 1:54:17 PM3/31/11
to openwfe...@googlegroups.com
Never mind, after reading our code again, I believe we took the wrong way.

The question about callbacks is still open, but I don't believe we need them anymore in the short time.

Thanks anyway,
-- Simone

John Mettraux

unread,
Mar 31, 2011, 2:32:28 PM3/31/11
to openwfe...@googlegroups.com

On Thu, Mar 31, 2011 at 07:54:17PM +0200, Simone Carletti wrote:
>
> Never mind, after reading our code again, I believe we took the wrong way.
>
> The question about callbacks is still open, but I don't believe we need them
> anymore in the short time.

Hello Simone,

what about the vanilla

---8<---
class SimoneParticipant < StorageParticipant
def consume(workitem)
pre_check(workitem)
super
end
def proceed(workitem)
post_check(workitem)
super
end
end

class ParticipantX < SimoneParticipant
protected
def pre_check(workitem)
# ...
end
def post_check(workitem)
# ...
end
end

engine.register 'x', ParticipantX
--->8---

?


Best regards,

--
John Mettraux - http://jmettraux.wordpress.com

Simone Carletti

unread,
Apr 1, 2011, 5:20:47 AM4/1/11
to openwfe...@googlegroups.com
Hi John,

On Thu, Mar 31, 2011 at 8:32 PM, John Mettraux <jmet...@openwfe.org> wrote:
class SimoneParticipant < StorageParticipant
 def consume(workitem)
   pre_check(workitem)
   super
 end
 def proceed(workitem)
   post_check(workitem)
   super
 end
end

for an unknown reason, I didn't consider this option. I was convinced that #reply was only an engine method.

This might probably do the trick. I'll give it a try and let you know.

Thanks,
Reply all
Reply to author
Forward
0 new messages