Module: Trailblazer::Activity::TaskWrap

Defined in:
lib/trailblazer/activity/task_wrap.rb,
lib/trailblazer/activity/task_wrap/runner.rb,
lib/trailblazer/activity/task_wrap/pipeline.rb,
lib/trailblazer/activity/task_wrap/call_task.rb,
lib/trailblazer/activity/task_wrap/extension.rb

Overview

Example with tracing:

Call the task_wrap circuit:

|-- Start
|-- Trace.capture_args   [optional]
|-- Call (call actual task) id: "task_wrap.call_task"
|-- Trace.capture_return [optional]
|-- Wrap::End

Defined Under Namespace

Modules: Runner Classes: Extension, Pipeline

Constant Summary collapse

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

Class Method Summary collapse

Class Method Details

.call_task(wrap_ctx, original_args) ⇒ Object

TaskWrap step that calls the actual wrapped task and passes all ‘original_args` to it.

It writes to wrap_ctx, wrap_ctx



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/trailblazer/activity/task_wrap/call_task.rb', line 6

def self.call_task(wrap_ctx, original_args)
  task = 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 = task.(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

.container_activity_for(activity, wrap_static: initial_wrap_static, id: nil, **config) ⇒ Object

This is the top-most “activity” that hosts the actual activity being run. The data structure is used in wrap_static_for, where we access :wrap_static to compile the effective taskWrap.

It’s also needed in Trace/Introspect and mimicks the host containing the actual activity.

DISCUSS: we could cache that on Strategy/Operation level.

merging the **config hash is 1/4 slower than before.


46
47
48
49
50
51
52
53
54
# File 'lib/trailblazer/activity/task_wrap.rb', line 46

def container_activity_for(activity, wrap_static: initial_wrap_static, id: nil, **config)
  {
    config: {
      wrap_static: {activity => wrap_static},
      **config
    },
    nodes:  Schema.Nodes([[id, activity]])
  }
end

.Extension(*inserts, merge: nil) ⇒ Object

inserts must be An Extension can be used for :wrap_runtime. It expects a collection of “friendly interface” arrays.

TaskWrap.Extension([task, id: "my_logger", append: "task_wrap.call_task"], [...])

If you want a wrap_static extension, wrap it using ‘Extension.WrapStatic.new`.



20
21
22
23
24
25
26
27
28
29
30
# File 'lib/trailblazer/activity/task_wrap/extension.rb', line 20

def self.Extension(*inserts, merge: nil)
  if merge
    Deprecate.warn caller_locations[0], "The :merge option for TaskWrap.Extension is deprecated and will be removed in 0.16.
Please refer to https://trailblazer.to/2.1/docs/activity.html#activity-taskwrap-static and have a great day."

    return Extension::WrapStatic.new(extension: Extension.new(*merge))
    # TODO: remove me once we drop the pre-friendly interface.
  end

  Extension.build(*inserts)
end

.initial_wrap_staticObject

:extension API Extend the static taskWrap from a macro or DSL call. Gets executed in Intermediate.call which also provides config.



34
35
36
# File 'lib/trailblazer/activity/task_wrap.rb', line 34

def initial_wrap_static
  INITIAL_WRAP_STATIC
end

.invoke(activity, args, wrap_runtime: {}, container_activity: container_activity_for(activity), **circuit_options) ⇒ Object

Compute runtime arguments necessary to execute a taskWrap per task of the activity. This method is the top-level entry, called only once for the entire activity graph.

:container_activity

the top-most “activity”. This only has to look like an Activity

and exposes a #[] interface so [:wrap_static] can be read and it's compatible to {Trace}.
It is the virtual activity that "hosts" the actual {activity}.


20
21
22
23
24
25
26
27
28
29
# File 'lib/trailblazer/activity/task_wrap.rb', line 20

def invoke(activity, args, wrap_runtime: {}, container_activity: container_activity_for(activity), **circuit_options)
  circuit_options = circuit_options.merge(
    runner:       TaskWrap::Runner,
    wrap_runtime: wrap_runtime,
    activity:     container_activity # for Runner. Ideally we'd have a list of all static_wraps here (even nested).
  )

  # signal, (ctx, flow), circuit_options =
  TaskWrap::Runner.(activity, args, **circuit_options)
end

.wrap_static_for(task, activity) ⇒ Object

Retrieve the static wrap config from activity.



47
48
49
50
51
# File 'lib/trailblazer/activity/task_wrap/runner.rb', line 47

def self.wrap_static_for(task, activity)
  activity.to_h
    .fetch(:config)
    .fetch(:wrap_static)[task] # the {wrap_static} for {task}.
end