2012/7/18 John Mettraux <[email protected]>: > 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: My first thoughts on this where: * Have an error handler * And a signaling participant and the end of the chain Just as a convention; (Although I do like the Ruote services (didn't know about them)) What would be 'wrong' about that approach? Grtz, Hartog -- 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
