Class: RubyReactor::Dsl::ComposeBuilder

Inherits:
Object
  • Object
show all
Includes:
TemplateHelpers
Defined in:
lib/ruby_reactor/dsl/compose_builder.rb

Constant Summary

Constants included from StepSignals

StepSignals::TAG

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from TemplateHelpers

#Failure, #Halt, #Skipped, #Success, #element, #input, #result, #value

Methods included from StepSignals

#fail!, #halt!, #skip!, #success!

Constructor Details

#initialize(name, composed_reactor_class = nil, reactor = nil, &block) ⇒ ComposeBuilder

Returns a new instance of ComposeBuilder.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/ruby_reactor/dsl/compose_builder.rb', line 10

def initialize(name, composed_reactor_class = nil, reactor = nil, &block)
  @name = name
  @composed_reactor_class = composed_reactor_class || (block ? Class.new(RubyReactor::Reactor) : nil)
  if @composed_reactor_class && @composed_reactor_class.name.nil? && reactor
    step_name_camel = name.to_s.split("_").map(&:capitalize).join
    parent_name = reactor.name

    full_name = "#{parent_name}::#{step_name_camel}"
    @composed_reactor_class.define_singleton_method(:name) { full_name }
    RubyReactor::Registry.register(full_name, @composed_reactor_class)
  end
  @reactor = reactor
  @argument_mappings = {}
  @retry_config = {}
end

Instance Attribute Details

#argument_mappingsObject

Returns the value of attribute argument_mappings.



8
9
10
# File 'lib/ruby_reactor/dsl/compose_builder.rb', line 8

def argument_mappings
  @argument_mappings
end

#composed_reactor_classObject

Returns the value of attribute composed_reactor_class.



8
9
10
# File 'lib/ruby_reactor/dsl/compose_builder.rb', line 8

def composed_reactor_class
  @composed_reactor_class
end

#nameObject

Returns the value of attribute name.



8
9
10
# File 'lib/ruby_reactor/dsl/compose_builder.rb', line 8

def name
  @name
end

Instance Method Details

#argument(composed_input_name, source) ⇒ Object



26
27
28
# File 'lib/ruby_reactor/dsl/compose_builder.rb', line 26

def argument(composed_input_name, source)
  @argument_mappings[composed_input_name] = source
end

#asyncObject

compose's async set the very same per-step hand-off flag the step DSL's did, so it goes with it. The exact migration is background before: :<this compose step> — that reproduces the old semantics precisely (this step and everything after it move to the worker) without the author having to identify a predecessor step.



35
36
37
38
39
40
41
42
43
44
45
# File 'lib/ruby_reactor/dsl/compose_builder.rb', line 35

def async(*)
  raise RubyReactor::Error::DeprecatedDslError.new(
    "`async` inside a `compose` block has been removed (it set the same ambiguous per-step " \
    "hand-off flag as `step`'s). Use `background before: :#{@name}` on the reactor to move " \
    ":#{@name} and every step after it to a worker — that reproduces the old behavior exactly. " \
    "For a nested reactor that should run INDEPENDENTLY of this one, use " \
    "`async_reactor :#{@name}, #{@composed_reactor_class&.name || "ChildReactor"}` instead; " \
    "for one step's worth of work, `async_step`.",
    step: @name
  )
end

#background(**kwargs) ⇒ Object

An inline compose child is a real reactor class, so it can declare its own hand-off point — delegate rather than making inline children the one place background is unavailable.



94
95
96
97
# File 'lib/ruby_reactor/dsl/compose_builder.rb', line 94

def background(**kwargs)
  ensure_composed_reactor_class!
  @composed_reactor_class.background(**kwargs)
end

#buildObject



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/ruby_reactor/dsl/compose_builder.rb', line 55

def build
  warn_if_child_has_ordered_lock!
  dependencies = extract_dependencies_from_mappings

  step_config = {
    name: @name,
    impl: RubyReactor::Step::ComposeStep,
    arguments: {
      composed_reactor_class: { source: RubyReactor::Template::Value.new(@composed_reactor_class) },
      argument_mappings: { source: RubyReactor::Template::Value.new(@argument_mappings) }
    },
    run_block: nil,
    compensate_block: nil,
    undo_block: nil,
    conditions: [],
    guards: [],
    dependencies: dependencies,
    args_validator: nil,
    output_validator: nil,
    retry_config: @retry_config.empty? ? (@reactor&.retry_defaults || {}) : @retry_config
  }

  RubyReactor::Dsl::StepConfig.new(step_config)
end

#compose(name, reactor_class = nil, &block) ⇒ Object



86
87
88
89
# File 'lib/ruby_reactor/dsl/compose_builder.rb', line 86

def compose(name, reactor_class = nil, &block)
  ensure_composed_reactor_class!
  @composed_reactor_class.compose(name, reactor_class, &block)
end

#retries(max_attempts: 3, backoff: :exponential, base_delay: 1) ⇒ Object



47
48
49
50
51
52
53
# File 'lib/ruby_reactor/dsl/compose_builder.rb', line 47

def retries(max_attempts: 3, backoff: :exponential, base_delay: 1)
  @retry_config = {
    max_attempts: max_attempts,
    backoff: backoff,
    base_delay: base_delay
  }
end

#step(name, &block) ⇒ Object

Delegate step definition methods to the composed reactor class



81
82
83
84
# File 'lib/ruby_reactor/dsl/compose_builder.rb', line 81

def step(name, &block)
  ensure_composed_reactor_class!
  @composed_reactor_class.step(name, &block)
end