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