Class: RubyReactor::Dsl::StepBuilder

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

Direct Known Subclasses

InterruptBuilder

Constant Summary

Constants included from StepSignals

StepSignals::TAG

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ValidationHelpers

#build_args_validator, #build_inline_validator, #build_macro_validator, #build_scalar_validator, #build_validation_schema, #create_input_validator

Methods included from TemplateHelpers

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

Methods included from StepSignals

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

Constructor Details

#initialize(name, impl = nil, reactor = nil) ⇒ StepBuilder

Returns a new instance of StepBuilder.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 12

def initialize(name, impl = nil, reactor = nil)
  @name = name
  @impl = impl
  @reactor = reactor
  @arguments = {}
  @run_block = nil
  @compensate_block = nil
  @undo_block = nil
  @conditions = []
  @guards = []
  @dependencies = []
  @arg_validations = []
  @validate_args_input = nil
  @args_validator = nil
  @output_validator = nil
  @retry_config = {}
end

Instance Attribute Details

#args_validatorObject

Returns the value of attribute args_validator.



9
10
11
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 9

def args_validator
  @args_validator
end

#argumentsObject

Returns the value of attribute arguments.



9
10
11
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 9

def arguments
  @arguments
end

#compensate_blockObject

Returns the value of attribute compensate_block.



9
10
11
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 9

def compensate_block
  @compensate_block
end

#conditionsObject

Returns the value of attribute conditions.



9
10
11
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 9

def conditions
  @conditions
end

#dependenciesObject

Returns the value of attribute dependencies.



9
10
11
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 9

def dependencies
  @dependencies
end

#guardsObject

Returns the value of attribute guards.



9
10
11
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 9

def guards
  @guards
end

#implObject

Returns the value of attribute impl.



9
10
11
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 9

def impl
  @impl
end

#nameObject

Returns the value of attribute name.



9
10
11
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 9

def name
  @name
end

#output_validatorObject

Returns the value of attribute output_validator.



9
10
11
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 9

def output_validator
  @output_validator
end

#retry_configObject

Returns the value of attribute retry_config.



9
10
11
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 9

def retry_config
  @retry_config
end

#run_blockObject

Returns the value of attribute run_block.



9
10
11
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 9

def run_block
  @run_block
end

#undo_blockObject

Returns the value of attribute undo_block.



9
10
11
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 9

def undo_block
  @undo_block
end

Instance Method Details

#argument(name, source, type = nil, transform: nil, **predicates) ⇒ Object



30
31
32
33
34
35
36
37
38
39
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 30

def argument(name, source, type = nil, transform: nil, **predicates)
  @arguments[name] = {
    source: source,
    transform: transform
  }

  return unless type || predicates.any?

  @arg_validations << [name, type, false, predicates]
end

#asyncObject

The per-step hand-off flag is gone. Only the FIRST flagged step in a reactor ever took effect — every later one was silently ignored — so this must fail at class-definition time rather than surprise someone at run time. Kept as a stub purely to say what to use instead.

Raises:



91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 91

def async(*)
  raise RubyReactor::Error::DeprecatedDslError.new(
    "`async` inside a `step` block has been removed: it was ambiguous (only the first " \
    "flagged step in a reactor ever took effect). Replacements:\n  " \
    "* `background after: :#{@name}` — hand every REMAINING step to a worker once " \
    ":#{@name} finishes in the calling process (declared on the reactor, not the step);\n  " \
    "* `background before: :#{@name}` — hand off starting WITH :#{@name};\n  " \
    "* `async_step :#{@name}` — dispatch just this step's work to its own job while the " \
    "reactor keeps running;\n  " \
    "* `async_reactor :name, ChildReactor` — dispatch a whole nested reactor independently.",
    step: @name
  )
end

#build(async_dispatch: nil) ⇒ Object

async_dispatch marks a step whose work is dispatched as an independent unit rather than run inline — :step for async_step, :reactor for async_reactor. Nil for an ordinary step.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 116

def build(async_dispatch: nil)
  step_config = {
    async_dispatch: async_dispatch,
    name: @name,
    impl: @impl,
    arguments: @arguments,
    run_block: @run_block,
    compensate_block: @compensate_block,
    undo_block: @undo_block,
    conditions: @conditions,
    guards: @guards,
    dependencies: @dependencies,
    args_validator: @args_validator || build_args_validator(@arg_validations, @validate_args_input),
    output_validator: @output_validator,
    retry_config: @retry_config.empty? ? (@reactor&.retry_defaults || {}) : @retry_config
  }

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

#compensate(&block) ⇒ Object



45
46
47
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 45

def compensate(&block)
  @compensate_block = block
end

#guard(&guard_fn) ⇒ Object



57
58
59
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 57

def guard(&guard_fn)
  @guards << guard_fn
end

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



105
106
107
108
109
110
111
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 105

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

#run(&block) ⇒ Object



41
42
43
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 41

def run(&block)
  @run_block = block
end

#undo(&block) ⇒ Object



49
50
51
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 49

def undo(&block)
  @undo_block = block
end

#validate_args(schema_or_validator = nil, &block) ⇒ Object

Cross-field rules over the whole resolved argument hash. Composes with per-argument inline validations declared via argument; the block (or pre-built schema) is applied last and wins on conflicts.



68
69
70
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 68

def validate_args(schema_or_validator = nil, &block)
  @validate_args_input = block || schema_or_validator
end

#validate_output(type = nil, **predicates, &block) ⇒ Object

Scalar-aware output validation. validate_output :integer, gteq?: 0 # single value validate_output do ... end # hash output validate_output SomeSchema # pre-built schema



76
77
78
79
80
81
82
83
84
85
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 76

def validate_output(type = nil, **predicates, &block)
  @output_validator =
    if block
      create_input_validator(block)
    elsif type.is_a?(Symbol) || type.is_a?(Module) || predicates.any?
      build_scalar_validator(type, predicates)
    elsif type
      create_input_validator(type)
    end
end

#wait_for(*step_names) ⇒ Object



61
62
63
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 61

def wait_for(*step_names)
  @dependencies.concat(step_names)
end

#where(&predicate) ⇒ Object



53
54
55
# File 'lib/ruby_reactor/dsl/step_builder.rb', line 53

def where(&predicate)
  @conditions << predicate
end