trailblazer-activity 0.9.0 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +10 -8
- data/CHANGES.md +32 -0
- data/Gemfile +1 -4
- data/LICENSE +1 -1
- data/README.md +19 -14
- data/Rakefile +2 -5
- data/lib/trailblazer/activity.rb +4 -16
- data/lib/trailblazer/activity/circuit.rb +29 -1
- data/lib/trailblazer/activity/config.rb +1 -0
- data/lib/trailblazer/activity/introspect.rb +11 -10
- data/lib/trailblazer/activity/schema.rb +2 -0
- data/lib/trailblazer/activity/schema/intermediate.rb +3 -3
- data/lib/trailblazer/activity/structures.rb +11 -12
- data/lib/trailblazer/activity/task_builder.rb +5 -1
- data/lib/trailblazer/activity/task_wrap.rb +14 -8
- data/lib/trailblazer/activity/task_wrap/inject.rb +2 -2
- data/lib/trailblazer/activity/task_wrap/pipeline.rb +1 -1
- data/lib/trailblazer/activity/task_wrap/runner.rb +3 -4
- data/lib/trailblazer/activity/testing.rb +78 -3
- data/lib/trailblazer/activity/version.rb +1 -1
- data/trailblazer-activity.gemspec +3 -3
- metadata +12 -11
- data/.rubocop-https---raw-githubusercontent-com-trailblazer-meta-master-rubocop-yml +0 -101
- data/.rubocop.yml +0 -7
- data/.rubocop_todo.yml +0 -900
- data/lib/trailblazer/activity/present.rb +0 -63
- data/lib/trailblazer/activity/trace.rb +0 -144
@@ -1,63 +0,0 @@
|
|
1
|
-
module Trailblazer
|
2
|
-
class Activity
|
3
|
-
# Task < Array
|
4
|
-
# [ input, ..., output ]
|
5
|
-
|
6
|
-
module Trace
|
7
|
-
# TODO: make this simpler.
|
8
|
-
module Present
|
9
|
-
module_function
|
10
|
-
|
11
|
-
INDENTATION = " |".freeze
|
12
|
-
STEP_PREFIX = "-- ".freeze
|
13
|
-
|
14
|
-
def default_renderer(task_node:, **)
|
15
|
-
[ task_node[:level], %{#{task_node[:name]}} ]
|
16
|
-
end
|
17
|
-
|
18
|
-
def call(stack, level: 1, tree: [], renderer: method(:default_renderer), **options)
|
19
|
-
tree(stack.to_a, level, tree: tree, renderer: renderer, **options)
|
20
|
-
end
|
21
|
-
|
22
|
-
def tree(stack, level, tree:, renderer:, **options)
|
23
|
-
tree_for(stack, level, options.merge(tree: tree))
|
24
|
-
|
25
|
-
nodes = tree.each_with_index.map do |task_node, position|
|
26
|
-
renderer.(task_node: task_node, position: position, tree: tree)
|
27
|
-
end
|
28
|
-
|
29
|
-
render_tree_for(nodes)
|
30
|
-
end
|
31
|
-
|
32
|
-
def render_tree_for(nodes)
|
33
|
-
nodes.map { |level, node|
|
34
|
-
indentation = INDENTATION * (level -1)
|
35
|
-
indentation = indentation[0...-1] + "`" if level == 1 || /End./.match(node) # start or end step
|
36
|
-
indentation + STEP_PREFIX + node
|
37
|
-
}.join("\n")
|
38
|
-
end
|
39
|
-
|
40
|
-
def tree_for(stack, level, tree:, **options)
|
41
|
-
stack.each do |lvl| # always a Stack::Task[input, ..., output]
|
42
|
-
input, output, nested = Trace::Level.input_output_nested_for_level(lvl)
|
43
|
-
|
44
|
-
task = input.task
|
45
|
-
|
46
|
-
graph = Introspect::Graph(input.activity)
|
47
|
-
|
48
|
-
name = (node = graph.find { |node| node[:task] == task }) ? node[:id] : task
|
49
|
-
name ||= task # FIXME: bullshit
|
50
|
-
|
51
|
-
tree << { level: level, input: input, output: output, name: name, **options }
|
52
|
-
|
53
|
-
if nested.any? # nesting
|
54
|
-
tree_for(nested, level + 1, options.merge(tree: tree))
|
55
|
-
end
|
56
|
-
|
57
|
-
tree
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
@@ -1,144 +0,0 @@
|
|
1
|
-
module Trailblazer
|
2
|
-
class Activity
|
3
|
-
module Trace
|
4
|
-
class << self
|
5
|
-
# Public entry point to activate tracing when running {activity}.
|
6
|
-
def call(activity, (ctx, flow_options), circuit_options={})
|
7
|
-
activity, (ctx, flow_options), circuit_options = Trace.arguments_for_call( activity, [ctx, flow_options], circuit_options ) # only run once for the entire circuit!
|
8
|
-
|
9
|
-
signal, (ctx, flow_options) = Activity::TaskWrap.invoke(activity, [ctx, flow_options], circuit_options)
|
10
|
-
|
11
|
-
return flow_options[:stack], signal, [ctx, flow_options]
|
12
|
-
end
|
13
|
-
|
14
|
-
alias_method :invoke, :call
|
15
|
-
|
16
|
-
def arguments_for_call(activity, (options, flow_options), **circuit_options)
|
17
|
-
tracing_flow_options = {
|
18
|
-
stack: Trace::Stack.new,
|
19
|
-
}
|
20
|
-
|
21
|
-
tracing_circuit_options = {
|
22
|
-
wrap_runtime: ::Hash.new(Trace.merge_plan), # DISCUSS: this overrides existing {:wrap_runtime}.
|
23
|
-
}
|
24
|
-
|
25
|
-
return activity, [ options, tracing_flow_options.merge(flow_options) ], circuit_options.merge(tracing_circuit_options)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
module_function
|
30
|
-
# Insertions for the trace tasks that capture the arguments just before calling the task,
|
31
|
-
# and before the TaskWrap is finished.
|
32
|
-
#
|
33
|
-
# @private
|
34
|
-
def merge_plan
|
35
|
-
TaskWrap::Pipeline::Merge.new(
|
36
|
-
[TaskWrap::Pipeline.method(:insert_before), "task_wrap.call_task", ["task_wrap.capture_args", Trace.method(:capture_args)]],
|
37
|
-
[TaskWrap::Pipeline.method(:append), nil, ["task_wrap.capture_return", Trace.method(:capture_return)]],
|
38
|
-
)
|
39
|
-
end
|
40
|
-
|
41
|
-
# taskWrap step to capture incoming arguments of a step.
|
42
|
-
def capture_args(wrap_config, original_args)
|
43
|
-
original_args = capture_for(wrap_config[:task], *original_args)
|
44
|
-
|
45
|
-
return wrap_config, original_args
|
46
|
-
end
|
47
|
-
|
48
|
-
# taskWrap step to capture outgoing arguments from a step.
|
49
|
-
def capture_return(wrap_config, original_args)
|
50
|
-
(original_options, original_flow_options, _) = original_args[0]
|
51
|
-
|
52
|
-
original_flow_options[:stack] << Entity::Output.new(
|
53
|
-
wrap_config[:task], {}, wrap_config[:return_signal]
|
54
|
-
).freeze
|
55
|
-
|
56
|
-
original_flow_options[:stack].unindent!
|
57
|
-
|
58
|
-
|
59
|
-
return wrap_config, original_args
|
60
|
-
end
|
61
|
-
|
62
|
-
# It's important to understand that {flow[:stack]} is mutated by design. This is needed so
|
63
|
-
# in case of exceptions we still have a "global" trace - unfortunately Ruby doesn't allow
|
64
|
-
# us a better way.
|
65
|
-
def capture_for(task, (ctx, flow), activity:, **circuit_options)
|
66
|
-
flow[:stack].indent!
|
67
|
-
|
68
|
-
flow[:stack] << Entity::Input.new(
|
69
|
-
task, activity, [ctx, ctx.inspect]
|
70
|
-
).freeze
|
71
|
-
|
72
|
-
return [ctx, flow], circuit_options.merge(activity: activity)
|
73
|
-
end
|
74
|
-
|
75
|
-
# Structures used in {capture_args} and {capture_return}.
|
76
|
-
# These get pushed onto one {Level} in a {Stack}.
|
77
|
-
#
|
78
|
-
# Level[
|
79
|
-
# Level[ ==> this is a scalar task
|
80
|
-
# Entity::Input
|
81
|
-
# Entity::Output
|
82
|
-
# ]
|
83
|
-
# Level[ ==> nested task
|
84
|
-
# Entity::Input
|
85
|
-
# Level[
|
86
|
-
# Entity::Input
|
87
|
-
# Entity::Output
|
88
|
-
# ]
|
89
|
-
# Entity::Output
|
90
|
-
# ]
|
91
|
-
# ]
|
92
|
-
Entity = Struct.new(:task, :activity, :data)
|
93
|
-
Entity::Input = Class.new(Entity)
|
94
|
-
Entity::Output = Class.new(Entity)
|
95
|
-
|
96
|
-
class Level < Array
|
97
|
-
def inspect
|
98
|
-
%{<Level>#{super}}
|
99
|
-
end
|
100
|
-
|
101
|
-
# @param level {Trace::Level}
|
102
|
-
def self.input_output_nested_for_level(level)
|
103
|
-
input = level[0]
|
104
|
-
output = level[-1]
|
105
|
-
|
106
|
-
output, nested = output.is_a?(Entity::Output) ? [output, level-[input, output]] : [nil, level[1..-1]]
|
107
|
-
|
108
|
-
return input, output, nested
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
# Mutable/stateful per design. We want a (global) stack!
|
113
|
-
class Stack
|
114
|
-
def initialize
|
115
|
-
@nested = Level.new
|
116
|
-
@stack = [ @nested ]
|
117
|
-
end
|
118
|
-
|
119
|
-
def indent!
|
120
|
-
current << indented = Level.new
|
121
|
-
@stack << indented
|
122
|
-
end
|
123
|
-
|
124
|
-
def unindent!
|
125
|
-
@stack.pop
|
126
|
-
end
|
127
|
-
|
128
|
-
def <<(args)
|
129
|
-
current << args
|
130
|
-
end
|
131
|
-
|
132
|
-
def to_a
|
133
|
-
@nested
|
134
|
-
end
|
135
|
-
|
136
|
-
private
|
137
|
-
|
138
|
-
def current
|
139
|
-
@stack.last
|
140
|
-
end
|
141
|
-
end # Stack
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|