module Trailblazer::Developer::Trace

Constants

Activity
Entity

Structures used in {capture_args} and {capture_return}. These get pushed onto one {Level} in a {Stack}.

Level[
  Level[              ==> this is a scalar task
    Entity::Input
    Entity::Output
  ]
  Level[              ==> nested task
    Entity::Input
    Level[
      Entity::Input
      Entity::Output
    ]
    Entity::Output
  ]
]

Public Class Methods

arguments_for_call(activity, (options, original_flow_options), **original_circuit_options) click to toggle source
# File lib/trailblazer/developer/trace.rb, line 20
def arguments_for_call(activity, (options, original_flow_options), **original_circuit_options)
  default_flow_options = {
    stack: Trace::Stack.new,

    input_data_collector: Trace.method(:default_input_data_collector),
    output_data_collector: Trace.method(:default_output_data_collector),
  }

  flow_options = { **default_flow_options, **Hash( original_flow_options ) }

  default_circuit_options = {
    wrap_runtime:  ::Hash.new(Trace.merge_plan), # DISCUSS: this overrides existing {:wrap_runtime}.
  }

  circuit_options = { **original_circuit_options, **default_circuit_options }

  return activity, [ options, flow_options ], circuit_options
end
call(activity, (ctx, flow_options), **circuit_options) click to toggle source

Public entry point to activate tracing when running {activity}.

# File lib/trailblazer/developer/trace.rb, line 10
def call(activity, (ctx, flow_options), **circuit_options)
  activity, (ctx, flow_options), circuit_options = Trace.arguments_for_call( activity, [ctx, flow_options], **circuit_options ) # only run once for the entire circuit!

  signal, (ctx, flow_options) = Activity::TaskWrap.invoke(activity, [ctx, flow_options], **circuit_options)

  return flow_options[:stack], signal, [ctx, flow_options]
end
Also aliased as: invoke
invoke(activity, (ctx, flow_options), **circuit_options)
Alias for: call

Public Instance Methods

capture_args(wrap_config, ((ctx, flow), circuit_options)) click to toggle source

It's important to understand that {flow} is mutated by design. This is needed so in case of exceptions we still have a “global” trace - unfortunately Ruby doesn't allow us a better way. taskWrap step to capture incoming arguments of a step.

# File lib/trailblazer/developer/trace.rb, line 56
def capture_args(wrap_config, ((ctx, flow), circuit_options))
  flow[:stack].indent!

  flow[:stack] << Entity::Input.new(
    wrap_config[:task],
    circuit_options[:activity],
    flow[:input_data_collector].call(wrap_config, [ctx, flow], circuit_options)
  ).freeze

  return wrap_config, [[ctx, flow], circuit_options]
end
capture_return(wrap_config, ((ctx, flow), circuit_options)) click to toggle source

taskWrap step to capture outgoing arguments from a step.

# File lib/trailblazer/developer/trace.rb, line 69
def capture_return(wrap_config, ((ctx, flow), circuit_options))
  flow[:stack] << Entity::Output.new(
    wrap_config[:task],
    {},
    flow[:output_data_collector].call(wrap_config, [ctx, flow], circuit_options)
  ).freeze

  flow[:stack].unindent!

  return wrap_config, [[ctx, flow], circuit_options]
end
default_input_data_collector(wrap_config, (ctx, _), circuit_options) click to toggle source
# File lib/trailblazer/developer/trace.rb, line 81
def default_input_data_collector(wrap_config, (ctx, _), circuit_options)
  graph = Trailblazer::Activity::Introspect::Graph(circuit_options[:activity])
  task  = wrap_config[:task]
  name  = (node = graph.find { |node| node[:task] == task }) ? node[:id] : task

  { ctx: ctx, task_name: name }
end
default_output_data_collector(wrap_config, (ctx, _), _) click to toggle source
# File lib/trailblazer/developer/trace.rb, line 89
def default_output_data_collector(wrap_config, (ctx, _), _)
  { ctx: ctx, signal: wrap_config[:return_signal] }
end
merge_plan() click to toggle source

Insertions for the trace tasks that capture the arguments just before calling the task, and before the TaskWrap is finished.

@private

# File lib/trailblazer/developer/trace.rb, line 45
def merge_plan
  Activity::TaskWrap::Pipeline::Merge.new(
    [Activity::TaskWrap::Pipeline.method(:insert_before), "task_wrap.call_task", ["task_wrap.capture_args",   Trace.method(:capture_args)]],
    [Activity::TaskWrap::Pipeline.method(:append),        nil,                   ["task_wrap.capture_return", Trace.method(:capture_return)]],
  )
end