
[o] port load26 (requires BlockParticipant)
[o] logger service
[o] test logger
[o] object full_dup
[o] engine#remove_service
[o] :receive or :receive_back for when workitems come back from participant
[o] emit :processes :launch :wfid
[o] emit :processes :terminate :wfid only
[o] arch doc
[o] verbose always on
[o] ev : :participants :register/:unregister
[o] test logger always on for tests (in-memory only)
[o] NullParticipant
[o] NoOpParticipant
[o] rufus-dollar
[o] variables in ProcessStatus (process level only)
[o] ProcessStatus#tree
[o] subprocess binding
[o] subprocess lookup
[o] participant lookup
[o] event : launch_sub
[o] event : :processes, :cancelled ?
[o] concurrence : over_if
[o] pool cleanup
[o] fexp : created_time
[o] ps : launched_time
[o] ps : #tags
[o] wi test (and fix) ${f:xyz}
[o] wi#to_h #from_h
[o] wi.params
[o] self rec for [main] process
[o] fexp.modified_time
[o] wfid_gen : rufus-mnemo
[o] fs_error_journal
[o] fs_error_journal : restart test
[o] do errors get removed after being replayed ? yes.
[o] cache storage
[o] fs storage
[o] tag (which implies variables)
[o] event : upon setting tag !
[o] event : upon leaving tag
[o] undo
[o] redo
[o] cancel-process (exp)
[o] cancel_process
[o] cancel
[o] on_error
[o] on_cancel
[o] iterator
[o] iterator : break, cancel, ...
[o] cursor
[o] cursor : jump to tag
[o] loop
[o] if
[o] equals
[o] unset
[o] cursor/loop/iterator : break-if rewind-if
[o] stop passing full exp in message, except for expression updates
[x] engine#reload
[o] participants shutdown
[o] stalled [participant] expressions restart (apply/reply ?)
    "re-apply on reload"
    http://groups.google.com/group/openwferu-users/browse_thread/thread/c2aa4b53d1664d45
[x] workitem.__result__ / why, the workitem itself is the result
[o] tracker
[o] sleep
[o] listen
[o] listen wfid="x"
[o] exploded scheduler
[x] wfid --> piid (stick with the funny old name)
[o] persisted tracker
[o] wfidgen.shutdown (close wfidgen.last)
[o] conditional for everybody
[o] timeout for everybody
[o] __timed_out__ = true ? (wi.fields)
[o] engine.processes()
[o] kill_process != cancel_process (need a way to not trigger on_cancel)
[o] pdef.to_dot (a beginning)
[o] @in_cancel, @in_error --> @state (active|cancelling|killing)
[o] wait
[o] listen
[o] Jason Allen's check about concurrence
[x] on_cancel => 'error' NO
[o] event on [un]setting variable
[o] condition : != ~= >= ....
[o] fs_participant
[o] participant : do thread (and do_not_thread)
[o] add test for error replay in participant
[o] forget : participant ? subprocess ? everybody
[o] Ruote.VERSION = "2.0.0" for Kenneth
[o] on_timeout => 'part|sub' (idea by hassox)
[o] on_timeout => 'error' (idea by hassox)
[o] exp : concurrent-iterator < concurrence
[o] exp : reserve
[o] exp : unset
[o] exp : save
[o] exp : restore (and its set-fields alias)
[o] participant : if EM is present use next_ or defer instead of Thread.new
[o] XML process definitions
[o] remote process definitions
[o] json process definitions
[o] check nested ${f:a.b.c}
[o] test : participant in error timeout (error should cancel timeout)
[o] nested set wi.fields['a.b.0'] = x
[o] nested save wi.fields['a.b.0'] = x
[o] parser.rb : test security check
[o] add Ruote::Launchitem
[o] participant#cancel pass flavour as well nil|:kill|:timeout
[o] BlockParticipant : |workitem, fexp|
[o] listeners
[o] engine.wait_for
[o] func tests : wire assert_no_errors back in
[o] timeout set by participant [implementation]
[o] test for wfids of errors in subprocesses !
[o] Ruote::Exp:: namespace for expressions
[o] exp : apply (ex-eval)
[o] apply : attributes to variables
[o] subprocess : attributes to variables
[o] concurrent_iterator :times => X
[o] iterator defaults to :to_v => 'i'
[o] concurrent_iterator defaults to :to_v => 'i'
[o] set "f:x" => "blah"; set "v:y" => [ 1, 2 ] (defaults to f:)
[o] subprocess :ref => uri
[o] participants : pass the &block under the option :block
[o] concurrence : :over_unless
[x] engine#register_subprocess (replaced by engine#variables)
[x] switch to JSON friendly pers format for flow expressions
[o] switch to JSON friendly pers format for workitems
[o] rewind :ref => 'tag_of_cursor_exp' (direct) :tag oriented.
[o] exp : error
[o] wait 0.500 / wait 60
[x] exp : reval : not needed, participants are here
[o] exp : inc ? if target is array, becomes append (not cons)
[o] exp : dec ? if target is array, then pop (not car)
[o] _if '${f:x} == ${f:y}'
[x] equals : equals "v:v" => "true"  NO => evokes assignment
[x] if : _if "v:v" => "true" ?  NO => evokes assignement
[x] deferred apply technique / not OK, with EM and next_tick / pro
[o] reserve : perhaps it's better to have an atomic get and set variable...
[o] clean up lookup_var/set_var into locate_var/lookup_var/set_var
[x] Sun Hao's up-to-date-tree idea ${f:participant_name} ps#resolved_tree
[o] error : when an error expression is cancelled, should the err get remove 
    from the process status ? yes.
[o] file logger / history service
[o] engine.process_history(wfid)
[o] add_branch :times/:branches
[o] cursor : :break_if / :break_unless
[o] exp : when (exploit :var :set event, or frequency)
[o] when : restart test
[o] when : cron frequency
[o] let listeners accept launchitems
[o] exp : cron
[o] exp : every
[o] write rt test for 'timeout'
[o] undo exp : alias to 'cancel'
[o] Andrew's at for timeouts (Chronic maybe)
[x] timeout :at and :after (timeout expression vanished)
[x] listen : should it forget its triggered children ? yes
[o] limit the number of msgs returned
[o] should redo/undo follow the example of command and add_branches ?
    everything through reply (receive)
    should re_apply not touch the state of its expression ?
[o] test undo when cancelling parent expression
[o] issue with :unless => '${f:index} == 2000'
[o] implement Engine#reply (Engine simply has to include ReceiverMixin
[o] listeners X receivers
[o] add_service(name, path, klass, opts={}) opts local to services (really?)
[o] add_branches : pass message to concurrent_iterator like a command expression
[o] clean up persists present in #apply
[o] maybe cancel should have a safely / redo_reply thing
[o] implement Storage#clear!(type)
[o] ruote/util/time.rb utc_to_s 'YYYY/MM/DD' --> 'YYYY-MM-DD' (regex friendly)
[x] store participant bytecode/AST ?
[o] ${r:puts(d("f:nada"))}
[o] :ruby_eval_allowed vs 'ruby_eval_allowed'
[o] check : what if a reply on a concurrence wants to save, whereas the
    concurrence terminated (got removed) meanwhile ?
    the reply returns true...
[o] implement StorageHistory
[x] nuke FsHistory ? keep
[o] EngineParticipant
[x] expstorage.to_dot
[o] process_status.to_dot
[o] EngineParticipant : don't wait in case of forget (reply could NEVER come !)
[x] align :forget behaviour on EngineParticipant forget... OK as it is
[o] engine.re_apply(fei, wi) (thanks Torsten)... :wi => x, :tree => y...
[o] ruote-dm 2.1
[o] :tree => Ruote.to_tree { participant 'alpha' }
[o] implement == eql? hash for workitem
[o] StorageParticipant#query(wfid, participant_name, {fields})
[x] break fs_history, prepare for dm_history
[o] part = engine.register_participant :alpha, StorageParticipant should work...
[o] concurrence :merge_type => 'stack'
[o] CompositeStorage.new('msgs' => AmqpStorage.new(''), ...)
[x] let the storage participant leverage Ruote::FlowExpressionId.from_id(s)
[o] Andrew's technique http://groups.google.com/group/openwferu-users/browse_thread/thread/c2aa4b53d1664d45/8523a1a5ee98fd71
[o] Avishai : LocalParticipant : repost dispatch message
[o] Rdoc Ruote::Engine.register_participant -> passing a block to a participant
    and perhaps also on
    http://ruote.rubyforge.org/implementing_participants.html (Avish)
[o] wrap workitem in process error ? for on_error consumption (thanks Oleg)
    doing workitem.fields['__error__'] = [ fei, time, error_message ]
[o] HashStorage should emit 'init persist fail' messages as well !
[o] Oleg's idea about participant on_reply
    http://groups.google.com/group/openwferu-users/browse_thread/thread/2e6a95708c10847b
    on_reply should be done in the receive action, not in Receiver
    thus, in the ParticipantExpression
[x] exp : step (jump to cursor tag ?) : there is already the jump expression
[x] auto-participant re-apply
[o] receiver should be OK with a storage or a context
[x] Avishai : Worker : hook for rejecting the dispatch message
[o] receiver / local participant : reply/forward/proceed/... mess : fix
[o] storage participant : accept string for fei
[o] => Ruote::FlowExpressionId.extract(x)
[o] fei : place engine id in fei.to_storage_id (and back)
[o] wait_for(:inactive) blocks until worker is inactive
[o] storage0.copy_to(storage1) / migrate_to as requested by Matt Nichols
[o] check if rufus-lru is still needed
[o] storage migration : eats all the memory :(
[x] remove dependency on rufus-scheduler
[o] engine.storage_participant
[o] engine.noisy = true shortcut
[o] (ft_27) set "v:mypart" => [ 'MyParticipant', {} ]
    binding a participant on the fly (just for this process)
[o] participant timeout as an instance method
[o] engine.process_wfids (lighter than engine.processes)

[ ] exp : exp (restricted form of eval ?)
[ ] exp : case (is it necessary ?)
[ ] exp : filter
[ ] exp : filter-definition
[x] exp : lose ?
[x] exp : parameter
[ ] exp : log : or could it be a participant ?

[ ] exp : defined (not really necessary)
[ ] exp : quote (not really necessary)
[ ] exp : field / attribute (not really necessary)
[ ] exp : variable (not really necessary)

[ ] conditional : rprefix ! ${r:x} is perhaps sufficient

[ ] define without name (__result__)

[ ] pooltool.ru

[ ] participant dispatch thread throttling ?

[ ] tailcall
[ ] subprocesses participants (alias ?)

[ ] __command__ + tag (rewind that cursor there, not the current one)

[ ] beanstalk [as a] workqueue ?

[ ] recursion : should cope with modified trees 'main' => :tree ??

[ ] user3 :rif => "!wi.fields['approvers'].include?('user3')" : 'in' operator

[ ] set :var => 'y' { '2342342' }

[ ] pause engine
[ ] pause process instance
    |
    would it mean something like placing a paused list in the storage
    and fetching it all the time ?

[ ] file/fs_listener [example] ?

[ ] tree.to_xml (require builder ?)
[ ] tree.to_rb

[ ] concurrence / concurrent_iterator : merge plugin ?
    use participant for that ?

[ ] restore : implement merge strategies

[ ] one file, no multi-process, persistence ? LateHashStorage ?

[ ] apply : ruby or xml (instead of just ast) ?

[ ] unify ruote/util/json and ruote/util/serializer

[ ] history.to_tree ?

[ ] Ruote.process_definition ... Ruote.method_missing or sequence ?

[ ] concurrence / concurrent_iterator : merge_type => 'discard' / 'ignore'
    keep track of the first "process sub id" ?

[ ] @children diff/undiff idea ?

[ ] write doc about engine options (multi-process !)
[ ] _if '${f:x} == ${f:y} || ${f:x} == ${f:z}'

[ ] document the dollar notation / substitution / extrapolation

[ ] condition : "${f:x} [is] empty" / this one is hard

[ ] ruote/exp/fe_set.rb:147: warning: already initialized constant PREFIX_REGEX

[ ] implement kill_process! (kill_expression! ?)

[ ] engine.force_reply_to_parent(fei) ?

[ ] :on_timeout => :rewind (break, jump to x)...
[ ] rewind 'x' where x is a tagname (command x)

[ ] repeat : have a counter in a variable (:to => x maybe) (subprocessid ?)

[ ] when : add test for cancelling when child has been triggered / is running

[ ] engine.cancel_forgotten_children(wfid) ?

[ ] port subprocess on_cancel test from ruote 0.9 http://groups.google.com/group/openwferu-users/t/75f02bdadf7b93eb

[ ] double-check on_cancel rewrite (ft_1_process_status)

[ ] verify get_last/get_raw logic, no + 0.0001...
[ ] case exp : smarter one ?
[ ] spare 1 get_msg by caching msg (but keep 'deleting')
[ ] [un]set_var : via message ? should be ok like that... Not much traffic there

[ ] empty iterator or concurrent-iterator, log ? crash ? empty while...
[ ] at expression ?

[ ] remove abort_on_exception=true

[ ] shell ? irb ? Shell.new(storage)
[ ] focus on fulldup or json.dup (via fulldup ?)

[ ] listen to participants/errors/tags {in|out}

[x] engine.on_error = 'participant_name' // 'subprocess_name'
    done at : http://github.com/jmettraux/ruote/commit/50292d954ff877f1f6615022216f346a7001b483
    `--> reverting that for now, too dangerous

[ ]  should __error__ contain the tree ?
[ ] engine.on_cancel = 'participant_name' // 'subprocess_name'

[ ] "business days" plugin

[ ] issue with ruote-kit and inpa participants...

[ ] participant :ref => '${f:nada}', :or => 'xyz'
    (look at OpenWFE manual, this feature already existed in there)
    http://www.openwfe.org/manual/ch06s02.html#expression_participant
    else-ref... list of participants...
    ref="alpha && bravo", ref="alpha||bravo" (|| parallel :( )

[ ] LocalParticipant def consume; handle; reply; end

[ ] lib/ruote/part/participant_list.rb l176 better error message !

[ ] find better solution than "get all schedules"

[ ] worker : minuteman, make it cron triggerable
    trap SIGUSR1 or USR2
    maybe it's expensive to fire a [worker] process each minute
    have to write the $$ (pid) somewhere for cron to pick it up

[ ] detach / attach segments of processes
[ ] clone process ? (could be used by {de|at}tach)

[ ] dollar.rb ${timestamp} ?

[ ] toto :task => 'maw the lawn', :within => '3d'

[ ] solve the ps#root_expression_for(fei) dilemma

[ ] re_apply_stalled
    http://groups.google.com/group/openwferu-users/browse_thread/thread/ff29f26d6b5fd135

[ ] engine.purge (arts style : worker.@msgs = [])

[ ] http://ruote.rubyforge.org/irclogs/ruote_2010-07-07.txt
    configuration issue
    maybe fail with a good error message when registering service...

[ ] participant 'toto', :while => '${not_good}' (really ?)

[ ] engine.register_from_dir() have a way to re-evaluate the dir
[o] OR remove engine.register_from_dir()
[o] AND provide a better register &block
[o] provide a mean for a participant to reject a workitem (intra plist)
    on_reply and now filter ?

[ ] rw : upgrade [register_]participant documentation

[ ] StorageParticipant#by_store[_name]
    maybe : reform the store_name system !

[ ] rename 'parser' to 'reader'

