Class: NucleusCore::Workflow
- Inherits:
-
Object
- Object
- NucleusCore::Workflow
- Defined in:
- lib/nucleus_core/workflow.rb
Defined Under Namespace
Constant Summary collapse
- INITIAL_STATE =
States
:initial
- CONTINUE =
Signals
:continue
- WAIT =
:wait
- OK =
Node statuses
:ok
- FAILED =
:failed
Instance Attribute Summary collapse
-
#context ⇒ Object
Returns the value of attribute context.
-
#nodes ⇒ Object
Returns the value of attribute nodes.
-
#process ⇒ Object
Returns the value of attribute process.
Class Method Summary collapse
Instance Method Summary collapse
-
#define ⇒ Object
Override this method to draw the workflow graph.
- #execute(signal = nil) ⇒ Object
- #init_nodes ⇒ Object
-
#initialize(process: nil, context: {}) ⇒ Workflow
constructor
A new instance of Workflow.
- #register_node(attrs = {}) ⇒ Object
- #start_node(signals = {}) ⇒ Object
- #validate_nodes! ⇒ Object
Constructor Details
#initialize(process: nil, context: {}) ⇒ Workflow
Returns a new instance of Workflow.
47 48 49 50 51 52 53 |
# File 'lib/nucleus_core/workflow.rb', line 47 def initialize(process: nil, context: {}) @nodes = {} @process = process || Process.new(INITIAL_STATE) @context = build_context(context) init_nodes end |
Instance Attribute Details
#context ⇒ Object
Returns the value of attribute context.
45 46 47 |
# File 'lib/nucleus_core/workflow.rb', line 45 def context @context end |
#nodes ⇒ Object
Returns the value of attribute nodes.
45 46 47 |
# File 'lib/nucleus_core/workflow.rb', line 45 def nodes @nodes end |
#process ⇒ Object
Returns the value of attribute process.
45 46 47 |
# File 'lib/nucleus_core/workflow.rb', line 45 def process @process end |
Class Method Details
.call(signal: nil, process: nil, context: {}) ⇒ Object
75 76 77 78 79 80 81 82 |
# File 'lib/nucleus_core/workflow.rb', line 75 def self.call(signal: nil, process: nil, context: {}) workflow = new(process: process, context: context) workflow.validate_nodes! workflow.execute(signal) [workflow.context, workflow.process] end |
.rollback(process:, context:) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/nucleus_core/workflow.rb', line 84 def self.rollback(process:, context:) workflow = new(process: process, context: context) visited = workflow.process.visited.clone visited.reverse_each do |state| node = workflow.nodes[state] next node.operation.rollback(context) if node.operation.is_a?(NucleusCore::Operation) next node.rollback.call(context) if node.rollback.is_a?(Proc) end end |
Instance Method Details
#define ⇒ Object
Override this method to draw the workflow graph
72 73 |
# File 'lib/nucleus_core/workflow.rb', line 72 def define end |
#execute(signal = nil) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/nucleus_core/workflow.rb', line 105 def execute(signal=nil) signal ||= CONTINUE current_state = process.state next_signal = (fetch_node(current_state)&.signals || {})[signal] current_node = fetch_node(next_signal) context.fail!("invalid signal: #{signal}") if current_node.nil? while next_signal status, next_signal, @context = execute_node(current_node, context) break if status == FAILED process.visit(current_node.state) current_node = fetch_node(next_signal) break if next_signal == WAIT end context rescue NucleusCore::Operation::Context::Error context rescue StandardError => e fail_context(@context, e) end |
#init_nodes ⇒ Object
67 68 69 |
# File 'lib/nucleus_core/workflow.rb', line 67 def init_nodes define end |
#register_node(attrs = {}) ⇒ Object
55 56 57 58 59 |
# File 'lib/nucleus_core/workflow.rb', line 55 def register_node(attrs={}) node = Node.new(attrs) @nodes[node.state] = node end |
#start_node(signals = {}) ⇒ Object
61 62 63 64 65 |
# File 'lib/nucleus_core/workflow.rb', line 61 def start_node(signals={}) raise ArgumentError, "#{self.class}##{__method__}: missing signals" if signals.empty? register_node(state: INITIAL_STATE, signals: signals) end |
#validate_nodes! ⇒ Object
96 97 98 99 100 101 102 103 |
# File 'lib/nucleus_core/workflow.rb', line 96 def validate_nodes! start_nodes = nodes.values.count do |node| node.state == INITIAL_STATE end raise ArgumentError, "#{self.class}: missing `:initial` start node" if start_nodes.zero? raise ArgumentError, "#{self.class}: more than one start node detected" if start_nodes > 1 end |