Class: ActiveSaga::Workflow

Inherits:
Object
  • Object
show all
Extended by:
DSL::Options, DSL::Signals, DSL::Steps
Defined in:
lib/active_saga/workflow.rb

Overview

Base class for defining workflows.

Direct Known Subclasses

SampleWorkflow

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from DSL::Options

defaults, extended, idempotency_key, resolve_defaults, timeout

Methods included from DSL::Steps

extended, inherited, step, step_definition, steps, task, wait_for_signal

Methods included from DSL::Signals

extended, inherited, signal, signal_handler_for

Constructor Details

#initialize(context:, execution_id: nil) ⇒ Workflow

Returns a new instance of Workflow.



66
67
68
69
# File 'lib/active_saga/workflow.rb', line 66

def initialize(context:, execution_id: nil)
  @context = context
  @execution_id = execution_id
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



10
11
12
# File 'lib/active_saga/workflow.rb', line 10

def context
  @context
end

#execution_idObject (readonly)

Returns the value of attribute execution_id.



10
11
12
# File 'lib/active_saga/workflow.rb', line 10

def execution_id
  @execution_id
end

Class Method Details

.build_step_payload(step, idx) ⇒ Object



40
41
42
43
44
45
46
47
48
# File 'lib/active_saga/workflow.rb', line 40

def build_step_payload(step, idx)
  {
    name: step.name.to_s,
    style: step.style.to_s,
    callable: callable_identifier(step),
    options: step.options,
    position: idx
  }
end

.callable_identifier(step) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/active_saga/workflow.rb', line 50

def callable_identifier(step)
  case step.style
  when :method
    step.name.to_s
  when :task
    step.callable.is_a?(Class) ? step.callable.name : step.callable.class.name
  when :block
    "block"
  when :wait
    "wait"
  else
    step.callable.respond_to?(:name) ? step.callable.name : step.callable.to_s
  end
end

.start(**attrs) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/active_saga/workflow.rb', line 13

def start(**attrs)
  options = attrs.dup
  explicit_idempotency_key = options.delete(:idempotency_key)
   = options.delete(:metadata) { {} }

  context = ActiveSaga::Context.new(options)
  workflow = new(context: context)
  workflow.before_start

  idempotency_key = explicit_idempotency_key || workflow.compute_idempotency_key
  store = ActiveSaga.configuration.store!

  execution = store.start_execution(
    workflow_class: name,
    context: context.to_h,
    steps: steps.map.with_index { |step, idx| build_step_payload(step, idx) },
    idempotency_key:,
    timeout: timeout,
    metadata: ( || {}).deep_symbolize_keys
  )

  ActiveSupport::Notifications.instrument("active_saga.execution.started",
    execution_id: execution.id, workflow: name)

  execution
end

Instance Method Details

#before_startObject



75
# File 'lib/active_saga/workflow.rb', line 75

def before_start; end

#call_step_callable(step_definition) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/active_saga/workflow.rb', line 84

def call_step_callable(step_definition)
  positional, keyword = resolve_arguments(step_definition)

  case step_definition.style
  when :method
    send(step_definition.name, *positional, **keyword)
  when :task
    run_task_step(step_definition, positional, keyword)
  when :block
    step_definition.callable.call(context, *positional, **keyword)
  when :wait
    :waiting
  else
    raise ActiveSaga::Errors::InvalidStep, "Unknown style #{step_definition.style}"
  end
end

#compute_idempotency_keyObject



77
78
79
80
81
82
# File 'lib/active_saga/workflow.rb', line 77

def compute_idempotency_key
  block = self.class.idempotency_key
  return unless block

  instance_exec(&block)
end

#ctxObject



71
72
73
# File 'lib/active_saga/workflow.rb', line 71

def ctx
  context
end