Module: Statesman::Machine
- Defined in:
- lib/statesman/machine.rb
Overview
The main module, that should be ‘extend`ed in to state machine classes.
Defined Under Namespace
Modules: ClassMethods
Class Method Summary collapse
- .included(base) ⇒ Object
-
.retry_conflicts(max_retries = 1) ⇒ Object
Retry any transitions that fail due to a TransitionConflictError.
Instance Method Summary collapse
- #allowed_transitions ⇒ Object
- #available_events ⇒ Object
- #can_transition_to?(new_state, metadata = {}) ⇒ Boolean
- #current_state ⇒ Object
- #execute(phase, initial_state, new_state, transition) ⇒ Object
- #history ⇒ Object
- #initialize(object, options = { transition_class: Statesman::Adapters::MemoryTransition }) ⇒ Object
- #last_transition ⇒ Object
- #transition_to(new_state, metadata = {}) ⇒ Object
- #transition_to!(new_state, metadata = {}) ⇒ Object
- #trigger(event_name, metadata = {}) ⇒ Object
- #trigger!(event_name, metadata = {}) ⇒ Object
Class Method Details
.included(base) ⇒ Object
11 12 13 14 |
# File 'lib/statesman/machine.rb', line 11 def self.included(base) base.extend(ClassMethods) base.send(:attr_reader, :object) end |
.retry_conflicts(max_retries = 1) ⇒ Object
Retry any transitions that fail due to a TransitionConflictError
17 18 19 20 21 22 23 24 25 26 |
# File 'lib/statesman/machine.rb', line 17 def self.retry_conflicts(max_retries = 1) retry_attempt = 0 begin yield rescue TransitionConflictError retry_attempt += 1 retry_attempt <= max_retries ? retry : raise end end |
Instance Method Details
#allowed_transitions ⇒ Object
195 196 197 198 199 |
# File 'lib/statesman/machine.rb', line 195 def allowed_transitions successors_for(current_state).select do |state| can_transition_to?(state) end end |
#available_events ⇒ Object
263 264 265 266 267 268 |
# File 'lib/statesman/machine.rb', line 263 def available_events state = current_state self.class.events.select do |_, transitions| transitions.key?(state) end.map(&:first) end |
#can_transition_to?(new_state, metadata = {}) ⇒ Boolean
205 206 207 208 209 210 211 212 |
# File 'lib/statesman/machine.rb', line 205 def can_transition_to?(new_state, = {}) validate_transition(from: current_state, to: new_state, metadata: ) true rescue TransitionFailedError, GuardFailedError false end |
#current_state ⇒ Object
190 191 192 193 |
# File 'lib/statesman/machine.rb', line 190 def current_state last_action = last_transition last_action ? last_action.to_state : self.class.initial_state end |
#execute(phase, initial_state, new_state, transition) ⇒ Object
246 247 248 249 |
# File 'lib/statesman/machine.rb', line 246 def execute(phase, initial_state, new_state, transition) callbacks = callbacks_for(phase, from: initial_state, to: new_state) callbacks.each { |cb| cb.call(@object, transition) } end |
#history ⇒ Object
214 215 216 |
# File 'lib/statesman/machine.rb', line 214 def history @storage_adapter.history end |
#initialize(object, options = { transition_class: Statesman::Adapters::MemoryTransition }) ⇒ Object
179 180 181 182 183 184 185 186 187 188 |
# File 'lib/statesman/machine.rb', line 179 def initialize(object, = { transition_class: Statesman::Adapters::MemoryTransition }) @object = object @transition_class = [:transition_class] @storage_adapter = adapter_class(@transition_class).new( @transition_class, object, self, ) send(:after_initialize) if respond_to? :after_initialize end |
#last_transition ⇒ Object
201 202 203 |
# File 'lib/statesman/machine.rb', line 201 def last_transition @storage_adapter.last end |
#transition_to(new_state, metadata = {}) ⇒ Object
251 252 253 254 255 |
# File 'lib/statesman/machine.rb', line 251 def transition_to(new_state, = {}) self.transition_to!(new_state, ) rescue TransitionFailedError, GuardFailedError false end |
#transition_to!(new_state, metadata = {}) ⇒ Object
218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/statesman/machine.rb', line 218 def transition_to!(new_state, = {}) initial_state = current_state new_state = new_state.to_s validate_transition(from: initial_state, to: new_state, metadata: ) @storage_adapter.create(initial_state, new_state, ) true end |
#trigger(event_name, metadata = {}) ⇒ Object
257 258 259 260 261 |
# File 'lib/statesman/machine.rb', line 257 def trigger(event_name, = {}) self.trigger!(event_name, ) rescue TransitionFailedError, GuardFailedError false end |
#trigger!(event_name, metadata = {}) ⇒ Object
231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/statesman/machine.rb', line 231 def trigger!(event_name, = {}) transitions = self.class.events.fetch(event_name) do raise Statesman::TransitionFailedError, "Event #{event_name} not found" end new_state = transitions.fetch(current_state) do raise Statesman::TransitionFailedError, "State #{current_state} not found for Event #{event_name}" end transition_to!(new_state.first, ) true end |