lib/ruote/engine/process_status.rb in ruote-2.1.10 vs lib/ruote/engine/process_status.rb in ruote-2.1.11

- old
+ new

@@ -36,24 +36,39 @@ # The expressions that compose the process instance. # attr_reader :expressions + # An array of the workitems currently in the storage participant for this + # process instance. + # + # Do not confuse with #workitems + # + attr_reader :stored_workitems + # An array of errors currently plaguing the process instance. Hopefully, # this array is empty. # attr_reader :errors - def initialize (context, expressions, errors) + # An array of schedules (open structs yielding information about the + # schedules of this process) + # + attr_reader :schedules + def initialize (context, expressions, stored_workitems, errors, schedules) + @expressions = expressions.collect { |e| Ruote::Exp::FlowExpression.from_h(context, e) } @expressions.sort! { |a, b| a.fei.expid <=> b.fei.expid } - @errors = errors.collect { |e| - ProcessError.new(e) } - @errors.sort! { |a, b| a.fei.expid <=> b.fei.expid } + @stored_workitems = stored_workitems.collect { |h| + Ruote::Workitem.new(h) + } + + @errors = errors.sort! { |a, b| a.fei.expid <=> b.fei.expid } + @schedules = schedules.sort! { |a, b| a['owner'].sid <=> b['owner'].sid } end # Returns the expression at the root of the process instance. # def root_expression @@ -132,27 +147,101 @@ # Returns the unique identifier for this process instance. # def wfid - begin - root_expression.fei.wfid - rescue - @errors.first.fei.wfid - end + @expressions.any? ? @expressions.first.fei.wfid : @errors.first.fei.wfid end + # For a process + # + # Ruote.process_definition :name => 'review', :revision => '0.1' do + # author + # reviewer + # end + # + # will yield 'review'. + # def definition_name root_expression.attribute('name') || root_expression.attribute_text end + # For a process + # + # Ruote.process_definition :name => 'review', :revision => '0.1' do + # author + # reviewer + # end + # + # will yield '0.1'. + # def definition_revision root_expression.attribute('revision') end + # Returns the 'position' of the process. + # + # pdef = Ruote.process_definition do + # alpha :task => 'clean car' + # end + # wfid = engine.launch(pdef) + # + # sleep 0.500 + # + # engine.process(wfid) # => [["0_0", "alpha", {"task"=>"clean car"}]] + # + # A process with concurrent branches will yield multiple 'positions'. + # + # It uses #workitems underneath. + # + def position + + workitems.collect { |wi| + r = [ wi.fei.sid, wi.participant_name ] + params = wi.fields['params'].dup + params.delete('ref') + r << params + r + } + end + + # Returns a list of the workitems currently 'out' to participants + # + # For example, with an instance of + # + # Ruote.process_definition do + # concurrence do + # alpha :task => 'clean car' + # bravo :task => 'sell car' + # end + # end + # + # calling engine.process(wfid).workitems will yield two workitems + # (alpha and bravo). + # + # Warning : do not confuse the workitems here with the workitems held + # in a storage participant or equivalent. + # + def workitems + + @expressions.select { |fexp| + fexp.is_a?(Ruote::Exp::ParticipantExpression) + }.collect { |fexp| + Ruote::Workitem.new(fexp.h.applied_workitem) + } + end + + # Returns a parseable UTC datetime string which indicates when the process + # was last active. + # + def last_active + + @expressions.collect { |fexp| fexp.h.put_at }.max + end + # Returns the process definition tree as it was when this process instance # was launched. # def original_tree @@ -168,79 +257,90 @@ def to_s "(process_status wfid '#{wfid}', " + "expressions #{@expressions.size}, " + - "errors #{@errors.size})" + "stored_workitems #{@stored_workitems.size}, " + + "errors #{@errors.size}, " + + "schedules #{@schedules.size}, " + + ")" end def inspect - s = "== #{self.class} ==\n" - s << " expressions : #{@expressions.size}\n" + s = [ "== #{self.class} ==" ] + s << " expressions : #{@expressions.size}" @expressions.each do |e| - s << " #{e.fei.to_storage_id} : #{e}\n" + s << " #{e.fei.to_storage_id} : #{e}" end - s << " errors : #{@errors.size}\n" + s << " errors : #{@errors.size}" @errors.each do |e| - s << " #{e.fei.to_storage_id} :\n" if e.fei - s << " #{e.inspect}\n" + s << " #{e.fei.to_storage_id} :" if e.fei + s << " #{e.inspect}" end + s << " schedules : #{@schedules.size}" + s << " stored workitems : #{@stored_workitems.size}" - s + s.join("\n") + "\n" end + # Returns a 'dot' representation of the process. A graph describing + # the tree of flow expressions that compose the process. + # def to_dot (opts={}) s = [ "digraph \"process wfid #{wfid}\" {" ] @expressions.each { |e| s.push(*e.send(:to_dot, opts)) } @errors.each { |e| s.push(*e.send(:to_dot, opts)) } s << "}" s.join("\n") end - def to_h + #-- + #def to_h + # h = {} + # %w[ + # wfid + # definition_name definition_revision + # original_tree current_tree + # variables tags + # ].each { |m| h[m] = self.send(m) } + # h['launched_time'] = launched_time + # h['last_active'] = last_active + # # all_variables and all_tags ? + # h['root_expression'] = nil + # h['expressions'] = @expressions.collect { |e| e.fei.to_h } + # h['errors'] = @errors.collect { |e| e.to_h } + # h + #end + #++ - h = {} - - %w[ - wfid - definition_name definition_revision - original_tree current_tree - variables tags - ].each { |m| h[m] = self.send(m) } - - h['launched_time'] = launched_time.to_s - - # all_variables and all_tags ? - - h['root_expression'] = nil - h['expressions'] = @expressions.collect { |e| e.fei.to_h } - h['errors'] = @errors.collect { |e| e.to_h } - - h - end - # Returns the current version of the process definition tree. If no # manipulation (gardening) was performed on the tree, this method yields # the same result as the #original_tree method. # def current_tree h = Ruote.decompose_tree(original_tree) @expressions.sort { |e0, e1| + e0.fei.expid <=> e1.fei.expid + }.each { |e| - tree = if v = e.tree[1]['_triggered'] + + trigger = e.tree[1]['_triggered'] + + tree = if trigger && trigger != 'on_re_apply' t = original_tree_from_parent(e).dup - t[1]['_triggered'] = v + t[1]['_triggered'] = trigger t else e.tree end + h.merge!(Ruote.decompose_tree(tree, e.fei.expid)) } Ruote.recompose_tree(h) end @@ -267,10 +367,9 @@ t = h[pos] return nil unless t t << [] - i = 0 loop do tt = recompose_tree(h, "#{pos}_#{i}") break unless tt