Module: Statesman::Machine
- Defined in:
- lib/statesman/machine.rb
Overview
The main module, that should be extended 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(metadata = {}) ⇒ Object
- #can_transition_to?(new_state, metadata = {}) ⇒ Boolean
- #current_state(force_reload: false) ⇒ Object
- #execute(phase, initial_state, new_state, transition) ⇒ Object
- #execute_on_failure(phase, initial_state, new_state, exception) ⇒ Object
- #history ⇒ Object
- #in_state?(*states) ⇒ Boolean
- #initialize(object, options = { transition_class: Statesman::Adapters::MemoryTransition, initial_transition: false, }) ⇒ Object
- #last_transition(force_reload: false) ⇒ Object
- #last_transition_to(state) ⇒ Object
- #reset ⇒ Object
- #transition_to(new_state, metadata = {}) ⇒ Object
- #transition_to!(new_state, metadata = {}) ⇒ Object
Class Method Details
.included(base) ⇒ Object
12 13 14 15 |
# File 'lib/statesman/machine.rb', line 12 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
18 19 20 21 22 23 24 25 26 27 |
# File 'lib/statesman/machine.rb', line 18 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(metadata = {}) ⇒ Object
278 279 280 281 282 |
# File 'lib/statesman/machine.rb', line 278 def allowed_transitions( = {}) successors_for(current_state).select do |state| can_transition_to?(state, ) end end |
#can_transition_to?(new_state, metadata = {}) ⇒ Boolean
292 293 294 295 296 297 298 299 |
# File 'lib/statesman/machine.rb', line 292 def can_transition_to?(new_state, = {}) validate_transition(from: current_state, to: new_state, metadata: ) true rescue TransitionFailedError, GuardFailedError false end |
#current_state(force_reload: false) ⇒ Object
269 270 271 272 |
# File 'lib/statesman/machine.rb', line 269 def current_state(force_reload: false) last_action = last_transition(force_reload: force_reload) last_action ? last_action.to_state : self.class.initial_state end |
#execute(phase, initial_state, new_state, transition) ⇒ Object
329 330 331 332 |
# File 'lib/statesman/machine.rb', line 329 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 |
#execute_on_failure(phase, initial_state, new_state, exception) ⇒ Object
324 325 326 327 |
# File 'lib/statesman/machine.rb', line 324 def execute_on_failure(phase, initial_state, new_state, exception) callbacks = callbacks_for(phase, from: initial_state, to: new_state) callbacks.each { |cb| cb.call(@object, exception) } end |
#history ⇒ Object
301 302 303 |
# File 'lib/statesman/machine.rb', line 301 def history @storage_adapter.history end |
#in_state?(*states) ⇒ Boolean
274 275 276 |
# File 'lib/statesman/machine.rb', line 274 def in_state?(*states) states.flatten.any? { |state| current_state == state.to_s } end |
#initialize(object, options = { transition_class: Statesman::Adapters::MemoryTransition, initial_transition: false, }) ⇒ Object
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/statesman/machine.rb', line 249 def initialize(object, = { transition_class: Statesman::Adapters::MemoryTransition, initial_transition: false, }) @object = object @transition_class = [:transition_class] @storage_adapter = adapter_class(@transition_class).new( @transition_class, object, self, ) if [:initial_transition] if history.empty? && self.class.initial_state @storage_adapter.create(nil, self.class.initial_state) end end send(:after_initialize) if respond_to? :after_initialize end |
#last_transition(force_reload: false) ⇒ Object
284 285 286 |
# File 'lib/statesman/machine.rb', line 284 def last_transition(force_reload: false) @storage_adapter.last(force_reload: force_reload) end |
#last_transition_to(state) ⇒ Object
288 289 290 |
# File 'lib/statesman/machine.rb', line 288 def last_transition_to(state) history.reverse.find { |transition| transition.to_state.to_sym == state.to_sym } end |
#reset ⇒ Object
340 341 342 |
# File 'lib/statesman/machine.rb', line 340 def reset @storage_adapter.reset end |
#transition_to(new_state, metadata = {}) ⇒ Object
334 335 336 337 338 |
# File 'lib/statesman/machine.rb', line 334 def transition_to(new_state, = {}) transition_to!(new_state, ) rescue TransitionFailedError, GuardFailedError false end |
#transition_to!(new_state, metadata = {}) ⇒ Object
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
# File 'lib/statesman/machine.rb', line 305 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 rescue TransitionFailedError => e execute_on_failure(:after_transition_failure, initial_state, new_state, e) raise rescue GuardFailedError => e execute_on_failure(:after_guard_failure, initial_state, new_state, e) raise end |