Module: Trailblazer::Operation::PublicCall

Included in:
Trailblazer::Operation
Defined in:
lib/trailblazer/operation/public_call.rb

Constant Summary collapse

INITIAL_WRAP_STATIC =
Activity::TaskWrap::Pipeline.new([Activity::TaskWrap::Pipeline.Row("task_wrap.call_task", method(:call_task))])

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.call_task(wrap_ctx, original_args) ⇒ Object

This TaskWrap step replaces the default call_task step for this very operation. Instead of invoking the operation using Operation.call, it does Operation.call_with_circuit_interface, so we don’t invoke Operation.call twice.

I don’t really like this “hack”, but it’s the only way until we get method overloading.



97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/trailblazer/operation/public_call.rb', line 97

def self.call_task(wrap_ctx, original_args) # DISCUSS: copied from {TaskWrap.call_task}.
  operation = wrap_ctx[:task]

  original_arguments, original_circuit_options = original_args

  # Call the actual task we're wrapping here.
  # puts "~~~~wrap.call: #{task}"
  return_signal, return_args = operation.call_with_circuit_interface(original_arguments, **original_circuit_options)

  # DISCUSS: do we want original_args here to be passed on, or the "effective" return_args which are different to original_args now?
  wrap_ctx = wrap_ctx.merge(return_signal: return_signal, return_args: return_args)

  return wrap_ctx, original_args
end

.options_for_public_call(options, flow_options = {}) ⇒ Object

Compile a Context object to be passed into the Activity::call.



74
75
76
# File 'lib/trailblazer/operation/public_call.rb', line 74

def self.options_for_public_call(options, flow_options = {})
  Trailblazer::Context(options, {}, flow_options[:context_options])
end

Instance Method Details

#call(options = {}, flow_options = {}, **circuit_options) ⇒ Object

Note:

Do not override this method as it will be removed in future versions. Also, you will break tracing.

This is the outer-most public ‘call` method that gets invoked when calling `Create.()`. The signature of this is `params, options, *containers`. This was a mistake, as the first argument could’ve been part of ‘options` hash in the first place.

Create.(params, runtime_data, *containers)

#=> Result<Context...>

In workflows/Nested compositions, this method is not used anymore and it might probably get removed in future versions of TRB. Currently, we use Operation::__call__ as an alternative.

Returns:

  • Operation::Railway::Result binary result object



16
17
18
19
20
# File 'lib/trailblazer/operation/public_call.rb', line 16

def call(options = {}, flow_options = {}, **circuit_options)
  return call_with_circuit_interface(options, **circuit_options) if options.is_a?(Array) # This is kind of a hack that could be well hidden if Ruby had method overloading. Goal is to simplify the call thing as we're fading out Operation::public_call anyway.

  call_with_public_interface_from_call(options, flow_options, **circuit_options)
end

#call_with_circuit_interface(args, **circuit_options) ⇒ signal, [ctx, flow_options]

This interface is used for all nested OPs (and the outer-most, too).

Parameters:

  • args (Array)
    • Contains [ctx, flow_options]

  • circuit_options (Hash)
    • Options to configure activity circuit

Returns:

  • (signal, [ctx, flow_options])


64
65
66
# File 'lib/trailblazer/operation/public_call.rb', line 64

def call_with_circuit_interface(args, **circuit_options)
  strategy_call(args, **circuit_options) # FastTrack#call
end

#call_with_flow_options(options, flow_options) ⇒ Object

TODO: remove when we stop supporting < 3.0.

alternatively, ctx aliasing is only available for Ruby > 2.7.


85
86
87
88
# File 'lib/trailblazer/operation/public_call.rb', line 85

def call_with_flow_options(options, flow_options)
  raise "[Trailblazer] `Operation.call_with_flow_options is deprecated in Ruby 3.0. Use `Operation.(options, flow_options)`" if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.0.0")
  call_with_public_interface(options, flow_options, {invoke_class: Activity::TaskWrap})
end

#call_with_public_interface(options, flow_options, invoke_class: Activity::TaskWrap, **circuit_options) ⇒ Operation::Railway::Result

Default @activity call interface which doesn’t accept circuit_options

@semi-public It’s OK to override this method.

Parameters:

  • args (Array)

    > [ctx, flow_options]

Returns:



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/trailblazer/operation/public_call.rb', line 38

def call_with_public_interface(options, flow_options, invoke_class: Activity::TaskWrap, **circuit_options)
  flow_options  = flow_options_for_public_call(flow_options)
  ctx           = options_for_public_call(options, flow_options)

  # Call the activity as it if was a step in an endpoint.

  # This will result in invoking {self.call_with_circuit_interface}.
  signal, (ctx, flow_options) = invoke_class.invoke(
    self,
    [ctx, flow_options],
    container_activity: Activity::TaskWrap.container_activity_for(self, wrap_static: initial_wrap_static), # we cannot make this static because of {self} unless we override {#inherited}.
    **circuit_options # this will always be an empty hash if coming from #{call_with_public_interface_from_call}.
  )

  # Result is successful if the activity ended with an End event derived from Railway::End::Success.
  Operation::Railway::Result(signal, ctx, flow_options)
end

#call_with_public_interface_from_call(options, flow_options, **circuit_options) ⇒ Object



23
24
25
26
27
28
29
# File 'lib/trailblazer/operation/public_call.rb', line 23

def call_with_public_interface_from_call(options, flow_options, **circuit_options)
  # normalize options.
  options = options
    .merge(circuit_options) # when using Op.call(params:, ...), {circuit_options} will always be ctx variables.

  call_with_public_interface(options, flow_options)
end

#flow_options_for_public_call(options = {}) ⇒ Object

@semi=public



79
80
81
# File 'lib/trailblazer/operation/public_call.rb', line 79

def flow_options_for_public_call(options = {})
  options
end

#initial_wrap_staticObject



114
115
116
# File 'lib/trailblazer/operation/public_call.rb', line 114

def initial_wrap_static
  INITIAL_WRAP_STATIC
end

#options_for_public_call(*args) ⇒ Object



68
69
70
# File 'lib/trailblazer/operation/public_call.rb', line 68

def options_for_public_call(*args)
  Operation::PublicCall.options_for_public_call(*args)
end