Class: LifecycleVM::VM

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/lifecycle_vm/vm.rb

Defined Under Namespace

Classes: Config, InvalidState, OpEntry

Constant Summary collapse

DEFAULT_START =

By default the lifecycle state machine starts at :start, ends at :exit, and immediately termiantes on op failure.

:start
DEFAULT_TERMINALS =
[:exit].freeze
DEFAULT_ON_OP_FAILURE =
:exit

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(memory = nil) ⇒ VM

Returns a new instance of VM.



138
139
140
# File 'lib/lifecycle_vm/vm.rb', line 138

def initialize(memory = nil)
  @memory = memory || config.memory_class.new
end

Class Attribute Details

.configConfig (readonly)

Returns the machine configuration.

Returns:

  • (Config)

    the machine configuration



123
124
125
# File 'lib/lifecycle_vm/vm.rb', line 123

def config
  @config
end

Instance Attribute Details

#memoryLifecycleVM::Memory (readonly)

The current VM memory

Returns:



128
129
130
# File 'lib/lifecycle_vm/vm.rb', line 128

def memory
  @memory
end

Class Method Details

.initial(state) ⇒ Object

Set the state to start execution at



102
103
104
105
# File 'lib/lifecycle_vm/vm.rb', line 102

def initial(state)
  @config ||= Config.new
  @config.initial_state = state
end

.memory_class(klass) ⇒ Object

Set the class to be instantiated to store VM memory



117
118
119
120
# File 'lib/lifecycle_vm/vm.rb', line 117

def memory_class(klass)
  @config ||= Config.new
  @config.memory_class = klass
end

.on(state, opts) ⇒ Object

Declare a state with an optional op and conditional transitions

Parameters:

  • state (Symbol)

    the name of the state

  • opts (Hash)

Options Hash (opts):

  • :do (LifecycleVM::OpBase) — default: nil

    the op to execute upon entering this state

  • :then (Symbol, Hash) — default: nil

    either the name of the state to transition do after executing :do, or a hash of the form { case: LifecycleVM::CondBase, when: Hash<_, [Symbol, Hash]> }



96
97
98
99
# File 'lib/lifecycle_vm/vm.rb', line 96

def on(state, opts)
  @config ||= Config.new
  @config.states[state] = State.new(state, opts)
end

.on_op_failure(state) ⇒ Object

Set the state to transition to if an op fails

Parameters:

  • state (Symbol)

    the state to transition to when any op fails. There may only be one declared failure handler for any VM.



84
85
86
87
# File 'lib/lifecycle_vm/vm.rb', line 84

def on_op_failure(state)
  @config ||= Config.new
  @config.on_op_failure = state
end

.terminal(*states) ⇒ Object

Set one or more states as states to halt execution at



108
109
110
111
112
113
114
# File 'lib/lifecycle_vm/vm.rb', line 108

def terminal(*states)
  @config ||= Config.new
  @config.terminal_states += states
  states.each do |state|
    @config.states[state] ||= State.new(state, {})
  end
end

Instance Method Details

#callObject

Note:

May never terminate!

Executes the VM until a terminal state is reached.



144
145
146
147
148
149
150
151
152
153
# File 'lib/lifecycle_vm/vm.rb', line 144

def call
  self.error_op = nil
  self.current_op = nil
  next_state = config.initial_state
  loop do
    next_state = do_state(next_state)
    break unless next_state
  end
  self
end

#configConfig

Returns the machine configuration.

Returns:

  • (Config)

    the machine configuration



131
132
133
# File 'lib/lifecycle_vm/vm.rb', line 131

def config
  self.class.config
end

#do_anonymous_op(op, following) ⇒ Object

Raises:



178
179
180
181
182
# File 'lib/lifecycle_vm/vm.rb', line 178

def do_anonymous_op(op, following)
  raise InvalidState.new(current_state.name, self) if op && current_op.executed?

  do_op(op, following)
end

#errorsHash<Symbol, Array<String>>

Returns errors from the errored op.

Returns:

  • (Hash<Symbol, Array<String>>)

    errors from the errored op



162
163
164
# File 'lib/lifecycle_vm/vm.rb', line 162

def errors
  error_op&.errors
end

#errors?Boolean

Did this vm exit with an errored op?

Returns:

  • (Boolean)

    true if the vm exited with an errored op



157
158
159
# File 'lib/lifecycle_vm/vm.rb', line 157

def errors?
  !!error_op&.errors?
end

#recovery_errorsHash<Symbol, Array<String>>

Returns errors from the op failure op.

Returns:

  • (Hash<Symbol, Array<String>>)

    errors from the op failure op



173
174
175
# File 'lib/lifecycle_vm/vm.rb', line 173

def recovery_errors
  current_op&.errors
end

#recovery_errors?Boolean

Did this vm encounter an error trying to recover from an errored op?

Returns:

  • (Boolean)

    true if an op associated with the op failure state errored



168
169
170
# File 'lib/lifecycle_vm/vm.rb', line 168

def recovery_errors?
  !!current_op&.errors?
end