Module: Trailblazer::Developer::Trace
- Defined in:
- lib/trailblazer/developer/trace.rb,
lib/trailblazer/developer/trace/tree.rb,
lib/trailblazer/developer/trace/stack.rb,
lib/trailblazer/developer/trace/present.rb,
lib/trailblazer/developer/trace/debugger.rb,
lib/trailblazer/developer/trace/debugger/normalizer.rb
Defined Under Namespace
Modules: Debugger, Present Classes: Captured, Stack, Tree
Class Method Summary collapse
- .arguments_for_call(activity, options, original_flow_options, **original_circuit_options) ⇒ Object
-
.call(activity, ctx, flow_options, **circuit_options) ⇒ Object
(also: invoke)
Public entry point to activate tracing when running activity.
-
.capture_args(wrap_config, ctx, flow), circuit_options) ⇒ Object
It’s important to understand that :stack is mutated by design.
-
.capture_return(wrap_config, ctx, flow), circuit_options) ⇒ Object
taskWrap step to capture outgoing arguments from a step.
- .Captured(captured_class, data_collector, wrap_config, ctx, flow), circuit_options) ⇒ Object
-
.default_input_data_collector(wrap_config, ctx, _), _) ⇒ Object
Called in #Captured.
-
.default_output_data_collector(wrap_config, ctx, _), _) ⇒ Object
Called in #Captured.
-
.task_wrap_extensions ⇒ Object
Insertions for the trace tasks that capture the arguments just before calling the task, and before the TaskWrap is finished.
-
.Tree(stack_end, level: 0, parent: nil) ⇒ Object
Builds a tree graph from a linear stack.
Class Method Details
.arguments_for_call(activity, options, original_flow_options, **original_circuit_options) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/trailblazer/developer/trace.rb', line 16 def arguments_for_call(activity, (, ), **) = { stack: Trace::Stack.new, input_data_collector: Trace.method(:default_input_data_collector), output_data_collector: Trace.method(:default_output_data_collector), } = {**, **Hash()} = { wrap_runtime: ::Hash.new(Trace.task_wrap_extensions), # DISCUSS: this overrides existing {:wrap_runtime}. } = {**, **} return activity, [, ], end |
.call(activity, ctx, flow_options, **circuit_options) ⇒ Object Also known as: invoke
Public entry point to activate tracing when running activity.
6 7 8 9 10 11 12 |
# File 'lib/trailblazer/developer/trace.rb', line 6 def call(activity, (ctx, ), **) activity, (ctx, ), = Trace.arguments_for_call( activity, [ctx, ], ** ) # only run once for the entire circuit! signal, (ctx, ) = Trailblazer::Activity::TaskWrap.invoke(activity, [ctx, ], **) return [:stack], signal, [ctx, ] end |
.capture_args(wrap_config, ctx, flow), circuit_options) ⇒ Object
It’s important to understand that :stack 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.
51 52 53 54 55 56 57 58 59 |
# File 'lib/trailblazer/developer/trace.rb', line 51 def capture_args(wrap_config, ((ctx, flow), )) original_args = [[ctx, flow], ] captured_input = Captured(Captured::Input, flow[:input_data_collector], wrap_config, original_args) flow[:stack] << captured_input return wrap_config, original_args end |
.capture_return(wrap_config, ctx, flow), circuit_options) ⇒ Object
taskWrap step to capture outgoing arguments from a step.
62 63 64 65 66 67 68 69 70 |
# File 'lib/trailblazer/developer/trace.rb', line 62 def capture_return(wrap_config, ((ctx, flow), )) original_args = [[ctx, flow], ] captured_output = Captured(Captured::Output, flow[:output_data_collector], wrap_config, original_args) flow[:stack] << captured_output return wrap_config, original_args end |
.Captured(captured_class, data_collector, wrap_config, ctx, flow), circuit_options) ⇒ Object
72 73 74 75 76 77 78 79 80 |
# File 'lib/trailblazer/developer/trace.rb', line 72 def Captured(captured_class, data_collector, wrap_config, ((ctx, flow), )) collected_data = data_collector.call(wrap_config, [[ctx, flow], ]) captured_class.new( # either Input or Output wrap_config[:task], [:activity], collected_data ).freeze end |
.default_input_data_collector(wrap_config, ctx, _), _) ⇒ Object
Called in #Captured. DISCUSS: this is where to start for a new Inspector implementation.
84 85 86 87 88 89 90 91 92 |
# File 'lib/trailblazer/developer/trace.rb', line 84 def default_input_data_collector(wrap_config, ((ctx, _), _)) # DISCUSS: would it be faster to access ctx via {original_args[0][0]}? # mutable, old_ctx = ctx.decompose # mutable, old_ctx = ctx, nil { # ctx: ctx.to_h.freeze, ctx_snapshot: ctx.to_h.collect { |k,v| [k, v.inspect] }.to_h, } # TODO: proper snapshot! end |
.default_output_data_collector(wrap_config, ctx, _), _) ⇒ Object
Called in #Captured.
95 96 97 98 99 100 101 102 103 104 |
# File 'lib/trailblazer/developer/trace.rb', line 95 def default_output_data_collector(wrap_config, ((ctx, _), _)) returned_ctx, _ = wrap_config[:return_args] # FIXME: snapshot! { # ctx: ctx.to_h.freeze, ctx_snapshot: returned_ctx.to_h.collect { |k,v| [k, v.inspect] }.to_h, signal: wrap_config[:return_signal] } end |
.task_wrap_extensions ⇒ Object
Insertions for the trace tasks that capture the arguments just before calling the task, and before the TaskWrap is finished.
40 41 42 43 44 45 |
# File 'lib/trailblazer/developer/trace.rb', line 40 def task_wrap_extensions Trailblazer::Activity::TaskWrap.Extension( [Trace.method(:capture_args), id: "task_wrap.capture_args", prepend: "task_wrap.call_task"], [Trace.method(:capture_return), id: "task_wrap.capture_return", append: nil], # append to the very end of tW. ) end |
.Tree(stack_end, level: 0, parent: nil) ⇒ Object
Builds a tree graph from a linear stack. Consists of Trailblazer::Developer::Trace::Tree::Node structures.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/trailblazer/developer/trace/tree.rb', line 49 def self.Tree(stack_end, level: 0, parent: nil) processed = [] nodes = [] # for {captured_input} we're gonna build a {Node}! captured_input, remaining = stack_end[0], stack_end[1..-1] raise unless captured_input.is_a?(Captured::Input) while next_captured = remaining[0] if next_captured.is_a?(Captured::Input) bla, _processed = Tree(remaining, level: level+1) nodes += [bla] processed += _processed remaining = remaining - processed else # Captured::Output raise unless next_captured.is_a?(Captured::Output) raise if next_captured.activity != captured_input.activity node = Tree::Node.new(level, captured_input, next_captured, nodes) return node, [captured_input, *processed, next_captured] # what nodes did we process here? end end end |