> On Fri, Sep 4, 2009 at 7:23 AM, John Mettraux<[email protected]> wrote: >> >> I was thinking about your concurrence { 1000.times { x } } ruote-dm / >> ruote 2.0 issue and I remembered that save was still silent (at least >> my version). So I changed that : >> >> >> http://github.com/jmettraux/ruote-dm/commit/e11a79bfda62787f88c5579f152b56aa6fad2404 >> >> With save silent, the jamming problem is way harder to detect. >> >> Sorry for being late on that one, even if you warned me about it long >> ago though :( > On Sat, Sep 5, 2009 at 2:07 AM, Jason wrote: > Hi John, > Thanks for adding this :) > > Since it's early Friday morning and I feel like rambling a bit, > here's a few things I was thinking when I was debugging this issue the > other day. I mentioned I noticed the engine was pulling dm > expressions from the DB one by one, moving up the tree. I'm wonder if > there's a more efficient way of doing this, for example, by pulling > more of the expression out into the dm participant table. So instead > of having to pull the svalue of each expression, you can use the power > of SQL to move around in the tree faster. I suggest this, of course, > without a good understanding of how ruote expression execution really > works. Is there a primer I can read somewhere? I come from a DB > architect background so I might be able to help design a faster table > implementation :)
Hi, there is a "primer" at : http://jmettraux.wordpress.com/2008/09/07/how-does-ruote-work/ but it's a bit outdated. Here is a quick "how it works" : given the process definition [ 'sequence', {}, [ [ 'participant', { 'ref' => 'alice' }, [] ], [ 'participant', { 'ref' => 'bob' }, [] ], ] ] what will happen is : ---8<--- p la {:wfid=>"20090905-rerikawa", :tree=>["define", {"name"=>"test"}, [["sequence", {}, [["participant", {"ref"=>"alice"}, []], ["participant", {"ref"=>"bob"}, []]]]]], :workitem=>"Workitem/"} e up {:expression=>"SequenceExpression/engine|20090905-rerikawa|0"} 0 sequence {"name"=>"test"} 0_0 sequence {} 0_0_0 participant {"ref"=>"alice"} 0_0_1 participant {"ref"=>"bob"} e ap {:tree=>["sequence", {"name"=>"test"}, [["sequence", {}, [["participant", {"ref"=>"alice"}, []], ["participant", {"ref"=>"bob"}, []]]]]], :fei=>"engine|20090905-rerikawa|0", :workitem=>"Workitem/engine|20090905-rerikawa|0", :variables=>Hash} e up {:expression=>"SequenceExpression/engine|20090905-rerikawa|0"} e ap {:fei=>"engine|20090905-rerikawa|0"} e up {:expression=>"SequenceExpression/engine|20090905-rerikawa|0_0"} e ap {:tree=>["sequence", {}, [["participant", {"ref"=>"alice"}, []], ["participant", {"ref"=>"bob"}, []]]], :fei=>"engine|20090905-rerikawa|0_0", :parent_id=>"engine|20090905-rerikawa|0", :workitem=>"Workitem/engine|20090905-rerikawa|0_0", :variables=>nil} e up {:expression=>"SequenceExpression/engine|20090905-rerikawa|0_0"} e ap {:fei=>"engine|20090905-rerikawa|0_0"} e up {:expression=>"ParticipantExpression/engine|20090905-rerikawa|0_0_0"} e ap {:tree=>["participant", {"ref"=>"alice"}, []], :fei=>"engine|20090905-rerikawa|0_0_0", :parent_id=>"engine|20090905-rerikawa|0_0", :workitem=>"Workitem/engine|20090905-rerikawa|0_0_0", :variables=>nil} e up {:expression=>"ParticipantExpression/engine|20090905-rerikawa|0_0_0"} e ap {:fei=>"engine|20090905-rerikawa|0_0_0"} w re {:workitem=>"Workitem/engine|20090905-rerikawa|0_0_0", :pname=>"alice"} e de {:fei=>"engine|20090905-rerikawa|0_0_0"} e re {:workitem=>"Workitem/engine|20090905-rerikawa|0_0_0", :fei=>"engine|20090905-rerikawa|0_0_0"} w di {:workitem=>"Workitem/engine|20090905-rerikawa|0_0_0", :pname=>"alice"} e up {:expression=>"SequenceExpression/engine|20090905-rerikawa|0_0"} e re {:fei=>"engine|20090905-rerikawa|0_0", :workitem=>"Workitem/engine|20090905-rerikawa|0_0_0"} e up {:expression=>"ParticipantExpression/engine|20090905-rerikawa|0_0_1"} e ap {:tree=>["participant", {"ref"=>"bob"}, []], :fei=>"engine|20090905-rerikawa|0_0_1", :parent_id=>"engine|20090905-rerikawa|0_0", :workitem=>"Workitem/engine|20090905-rerikawa|0_0_1", :variables=>nil} e up {:expression=>"ParticipantExpression/engine|20090905-rerikawa|0_0_1"} e ap {:fei=>"engine|20090905-rerikawa|0_0_1"} w re {:workitem=>"Workitem/engine|20090905-rerikawa|0_0_1", :pname=>"bob"} e de {:fei=>"engine|20090905-rerikawa|0_0_1"} e re {:workitem=>"Workitem/engine|20090905-rerikawa|0_0_1", :fei=>"engine|20090905-rerikawa|0_0_1"} w di {:workitem=>"Workitem/engine|20090905-rerikawa|0_0_1", :pname=>"bob"} e de {:fei=>"engine|20090905-rerikawa|0_0"} e re {:fei=>"engine|20090905-rerikawa|0_0", :workitem=>"Workitem/engine|20090905-rerikawa|0_0"} e de {:fei=>"engine|20090905-rerikawa|0"} e re {:fei=>"engine|20090905-rerikawa|0", :workitem=>"Workitem/engine|20090905-rerikawa|0"} p te {:wfid=>"20090905-rerikawa", :workitem=>"Workitem/engine|20090905-rerikawa|0"} --->8--- where "e" means "expressions", "p" "processes", "w" "workitems", "up" "update" (a call to expression#persist), "ap" "apply", "re" "reply", "te" "terminate", "di" "dispatch" and "la" means "launch". You can get that output but commenting in that "noisy" function call : http://github.com/jmettraux/ruote/blob/88c4c90e97ba2a467ea5779395f8f3664edcb5d0/test/functional/eft_2_sequence.rb#L52 and running test/functional/eft_2_sequence.rb ruby19 test/functional/eft_2_sequence.rb -n test_alice_bob_sequence Launching a process instance means applying its root expression. Applying the root expression means instantiating a sequence expression and persisting it immediately, then applying it. Following the sequence implementation http://github.com/jmettraux/ruote/blob/88c4c90e97ba2a467ea5779395f8f3664edcb5d0/lib/ruote/exp/fe_sequence.rb the sequence will apply its children one by one (persist, apply). Having a child reply triggers the next child. The goal of this frenetic activity is to have a consistent state persisted at any time. Any expression may not reply, or reply after the engine gets restarted in some way. Granted optimizations are possible (the most obvious one is the cache that gets actived when :expstorage_cache is set to true, but it's only a read optimization and is not compatible with multi-process deployments). And when developing optimization, one has to keep in mind that expressions' trees may be changed (in-flight process modification). OK, maybe it doesn't apply for your organization, then you're free to optimize without caring about changing trees, but for the deployments I have, in-flight process modification makes sense. I hope these hints will help you understand the design, design decisions and trade-offs behind ruote. Your questions are welcome in this mailing list. 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 -~----------~----~----~----~------~----~------~--~---
