Thank you very much for your detailed explanation. 

For easy of implementation I want to store this information in the same 
place where the participant is being stored. I really didnt want to make a 
table in a DB.
I really liked the approach of using a listener for events but couldn't 
make it work.

I made a participan called finalized and registered it like this
    @engine.register_participant 'finalized', Ruote::StorageParticipant

I am not sure if this is the best thing to do but it will keep the workflow 
in this step forever, so I can always ask for this wfid and get 'finalized' 
as step
I have tried this:
   @engine.on_terminate = 'finalized' 
but it does not call the participant when the workflow is finalized. 
When I have the participant 'finalized' in the workflow itself it works. 

So, I would need to write 'finalized' as last participant in all my 
workflows. What is not very elegant but I prefer that to the other 
approaches. 
Any idea why  @engine.on_terminate = 'finalized'  does not work? 

Regards


On Wednesday, July 18, 2012 1:35:28 PM UTC+9, John Mettraux wrote:
>
>
> On Tue, Jul 17, 2012 at 07:58:08PM -0700, jordi wrote: 
> > 
> > We are using Ruote inside a web service that needs to answer to its 
> users 
> > if its job (implemented as a workflow) has finished correctly or not. 
> > 
> > Using engine.process(wfid) we get information about this wfid so we tell 
> > the users when the process is running or had some error. 
> > 
> > The problem is that we can not distinguish between a wfid that we have 
> > never run (an incorrect wfid) and a wfid that passed through the system 
> and 
> > finished already (it seems that Ruote forgets about finished wfids) 
>
> Hello Jordi, 
>
> welcome to the ruote mailing list. 
>
> Ruote behaves a bit like an operating system. You run processes, they have 
> PIDs and when they terminate, well the PID points to nothing (or to a new 
> process). Unlike an operating system, ruote (at least its most common wfid 
> generation routines) don't re-use wfids (provided the clocks are not 
> wrong). 
>
> Unfortunately, it means it's up to you to do the gone process / wfids 
> accounting. 
>
> > I think this is a common issue to have and surely there is a best 
> practice 
> > on how to manage this situation but I have not found anything relevant 
> in 
> > this mailing list. 
> > What's the best way to handle this situation? 
>
> I don't know the details of your ruote use so I cannot tell you what is 
> the 
> best way. If I knew the details, I'd probably say something that is off 
> and 
> wrong anyway (I'm an average human with a small head). 
>
> Let's enumerate a few variants to help you pick one. 
>
>
> == the logger 
>
> Let's use the default logger, it keeps track of the last 147 msgs, maybe 
> it 
> still knows about the process instance. 
>
>   #engine = Ruote::Engine.new(...) # old style 
>   dashboard = Ruote::Dashboard.new(...) 
>
>   class << dashboard 
>
>     def status(wfid) 
>
>       if ps(wfid) 
>         "RUNNING" 
>       elsif logger.log.find { |msg| msg['wfid'] == wfid } 
>         "DONE" 
>       else 
>         "UNKNOWN" # never ran or was forgotten 
>       end 
>     end 
>   end 
>
> Disadvantages: 
> * It really forgets after a while 
> * Only works for the "local" work (it doesn't work in multi-worker setups) 
>
>
> == the history 
>
> By default, ruote has a in-memory history service running, much like the 
> logger above, but it tracks the last 1000 msgs. Like the logger, it's only 
> local to a worker, so it doesn't work in multi-worker setups. 
>
> But you can setup a Ruote::StorageHistory to keep track of history in the 
> storage (so if you use ruote-sequel with PostgreSQL, the history will end 
> up 
> in that database). 
>
> Use example: 
>
>   
> https://github.com/jmettraux/ruote/blob/e5996817d09313ebc19b5586dbc9671f99d55420/test/functional/ft_36_storage_history.rb
>  
>
> We could thus write: 
>
>   dashboard = Ruote::Dashboard.new(...) 
>
>   dashboard.add_service( 
>     'history', 'ruote/log/storage_history', 'Ruote::StorageHistory') 
>
>   class << dashboard 
>
>     def status(wfid) 
>
>       if ps(wfid) 
>         "RUNNING" 
>       elsif context.history.by_wfid(wfid) 
>         "DONE" 
>       else 
>         "NONE" 
>       end 
>     end 
>   end 
>
> Disadvantages: 
> * It stores the whole history for all the processes (unless you provide an 
> alternate implementation that only stores when process terminates) 
>
>
> == the on_terminate registry 
>
> Write a ruote service that observes termination and persists terminated 
> wfids. 
>
> It'd look like: 
>
>   dashboard = Ruote::Dashboard.new(...) 
>
>   class Acme::Observer 
>     def initialize(context, options={}) 
>     end 
>     def on_msg(msg) 
>       next unless msg['action'] == 'terminated' 
>       $database.terminated_wfids << msg['wfid'] 
>     end 
>   end 
>
>   dashboard.add_service('observer', Acme::Observer) 
>
>   class << dashboard 
>
>     def status(wfid) 
>
>       if ps(wfid) 
>         "RUNNING" 
>       elsif $database.terminated_wfids.include?(wfid) 
>         "DONE" 
>       else 
>         "NONE" 
>       end 
>     end 
>   end 
>
>
> == ??? 
>
> There is probably a better solution, adapted to your system and so on... 
>
> I've seen other approaches where people do no polling at all and 
> immediately 
> notify clients of terminated processes. 
>
>
> I hope it'll help. Best regards, 
>
> -- 
> John Mettraux - http://lambda.io/jmettraux 
>
>

-- 
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

Reply via email to