trailblazer-circuit 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.md +4 -0
- data/lib/trailblazer/circuit/trace.rb +17 -14
- data/lib/trailblazer/circuit/version.rb +1 -1
- data/lib/trailblazer/circuit/wrapped.rb +49 -35
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d3c9b6666028fb2423dace64b0d84dfd67427e3a
|
4
|
+
data.tar.gz: a2ec4fb343197e3c512a0a0bb1c1a924ecdbee57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 72059d24e47902a25d385fd8103907bec6bcdccfbf1bccc443779c2b9d9390bd37c9cced154089aff1741f8974d586350e615ee98a422e32bd89957dc2974cf6
|
7
|
+
data.tar.gz: 5a9312bd96dafe6e8675a17c0b8f6c6f32504a15437f48ade8f2131f8c0178ba458456f3102b03d62e1beab93bc08c56c7e7abafdd6c30ab4707e0fcf5bb91c8
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# 0.0.5
|
2
|
+
|
3
|
+
* The `Wrapped::Runner` now applies `Alterations` to each task's `Circuit`. This means you can inject `:task_alterations` into `Circuit#call`, which will then be merged into the task's original circuit, and then run. While this might sound like crazy talk, this allows any kind of external injection (tracing, input/output contracts, step dependency injections, ...) for specific or all tasks of any circuit.
|
4
|
+
|
1
5
|
# 0.0.4
|
2
6
|
|
3
7
|
* Simpler tracing with `Stack`.
|
@@ -7,19 +7,12 @@ module Trailblazer
|
|
7
7
|
# puts Trailblazer::Circuit::Present.tree(stack) # renders the trail.
|
8
8
|
module Trace
|
9
9
|
def self.call(activity, direction, options, flow_options={})
|
10
|
-
# activity_wrap is the circuit/pipeline that wraps each step and implements tracing (and more, like input/output contracts, etc!).
|
11
|
-
activity_wrap = Activity::Before( Activity::Wrapped::Activity, Activity::Wrapped::Call, Trace.method(:capture_args), direction: Right )
|
12
|
-
activity_wrap = Activity::Before( activity_wrap, Activity::Wrapped::Activity[:End], Trace.method(:capture_return), direction: Right )
|
13
|
-
|
14
|
-
step_runners = {
|
15
|
-
nil => activity_wrap, # call all steps with tracing.
|
16
|
-
}
|
17
|
-
|
18
10
|
tracing_flow_options = {
|
19
|
-
runner:
|
20
|
-
stack:
|
21
|
-
|
22
|
-
|
11
|
+
runner: Activity::Wrapped::Runner,
|
12
|
+
stack: Trace::Stack.new,
|
13
|
+
wrap_alterations: Activity::Wrapped::Alterations.new(Trace.Alterations),
|
14
|
+
task_wraps: Activity::Wrapped::Wraps.new(Activity::Wrapped::Activity),
|
15
|
+
debug: {}, # TODO: set that in Activity::call?
|
23
16
|
}
|
24
17
|
|
25
18
|
direction, options, flow_options = activity.( direction, options, tracing_flow_options.merge(flow_options) )
|
@@ -27,16 +20,26 @@ module Trailblazer
|
|
27
20
|
return flow_options[:stack].to_a, direction, options, flow_options
|
28
21
|
end
|
29
22
|
|
23
|
+
# TODO: test alterations with any wrap_circuit.
|
24
|
+
|
25
|
+
# Default tracing tasks to be plugged into the wrap circuit.
|
26
|
+
def self.Alterations
|
27
|
+
[
|
28
|
+
->(wrap_circuit) { Activity::Before( wrap_circuit, Activity::Wrapped::Call, Trace.method(:capture_args), direction: Right ) },
|
29
|
+
->(wrap_circuit) { Activity::Before( wrap_circuit, wrap_circuit[:End], Trace.method(:capture_return), direction: Right ) },
|
30
|
+
]
|
31
|
+
end
|
32
|
+
|
30
33
|
def self.capture_args(direction, options, flow_options, wrap_config, original_flow_options)
|
31
34
|
original_flow_options[:stack].indent!
|
32
35
|
|
33
|
-
original_flow_options[:stack] << [ wrap_config[:
|
36
|
+
original_flow_options[:stack] << [ wrap_config[:task], :args, nil, options.dup, original_flow_options[:debug] ]
|
34
37
|
|
35
38
|
[ direction, options, flow_options, wrap_config, original_flow_options ]
|
36
39
|
end
|
37
40
|
|
38
41
|
def self.capture_return(direction, options, flow_options, wrap_config, original_flow_options)
|
39
|
-
original_flow_options[:stack] << [ wrap_config[:
|
42
|
+
original_flow_options[:stack] << [ wrap_config[:task], :return, flow_options[:result_direction], options.dup ]
|
40
43
|
|
41
44
|
original_flow_options[:stack].unindent!
|
42
45
|
|
@@ -1,9 +1,52 @@
|
|
1
1
|
class Trailblazer::Circuit
|
2
|
+
# Lingo: task_wrap
|
2
3
|
module Activity::Wrapped
|
3
|
-
#
|
4
|
+
# The runner is passed into Circuit#call( runner: Runner ) and is called for every task in the circuit.
|
5
|
+
# Its primary job is to actually `call` the task.
|
6
|
+
#
|
7
|
+
# Here, we extend this, and wrap the task `call` into its own pipeline, so we can add external behavior per task.
|
8
|
+
class Runner
|
9
|
+
# private flow_options[ :task_wraps ] # DISCUSS: move to separate arg?
|
10
|
+
# @api private
|
11
|
+
def self.call(task, direction, options, task_wraps:raise, wrap_alterations:{}, **flow_options)
|
12
|
+
# TODO: test this decider!
|
13
|
+
task_wrap = task_wraps[task] || raise("test me!")
|
14
|
+
task_wrap = wrap_alterations.(task, task_wrap)
|
15
|
+
|
16
|
+
wrap_config = { task: task }
|
17
|
+
|
18
|
+
# Call the task_wrap circuit:
|
19
|
+
# |-- Start
|
20
|
+
# |-- Trace.capture_args [optional]
|
21
|
+
# |-- Call (call actual task)
|
22
|
+
# |-- Trace.capture_return [optional]
|
23
|
+
# |-- End
|
24
|
+
# Pass empty flow_options to the task_wrap, so it doesn't infinite-loop.
|
25
|
+
task_wrap.( task_wrap[:Start], options, {}, wrap_config, flow_options.merge( task_wraps: task_wraps, wrap_alterations: wrap_alterations) )
|
26
|
+
end
|
27
|
+
end # Runner
|
28
|
+
|
29
|
+
class Wraps
|
30
|
+
def initialize(default, hash={})
|
31
|
+
@default, @hash = default, hash
|
32
|
+
end
|
33
|
+
|
34
|
+
def [](task)
|
35
|
+
@hash.fetch(task) { @default }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class Alterations < Wraps
|
40
|
+
# Find alterations for `task` and apply them to `task_wrap`.
|
41
|
+
# This usually means that tracing steps/tasks are added, input/output contracts added, etc.
|
42
|
+
def call(task, task_wrap)
|
43
|
+
self[task].
|
44
|
+
inject(task_wrap) { |circuit, alteration| alteration.(circuit) }
|
45
|
+
end
|
46
|
+
end
|
4
47
|
|
5
48
|
def self.call_activity(direction, options, flow_options, wrap_config, original_flow_options)
|
6
|
-
task = wrap_config[:
|
49
|
+
task = wrap_config[:task]
|
7
50
|
|
8
51
|
# Call the actual task we're wrapping here.
|
9
52
|
wrap_config[:result_direction], options, flow_options = task.( direction, options, original_flow_options )
|
@@ -13,46 +56,17 @@ class Trailblazer::Circuit
|
|
13
56
|
|
14
57
|
Call = method(:call_activity)
|
15
58
|
|
16
|
-
# Output = ->(direction, options, flow_options) { [direction, options, flow_options] }
|
17
|
-
|
18
59
|
class End < Trailblazer::Circuit::End
|
19
60
|
def call(direction, options, flow_options, wrap_config, *args)
|
20
|
-
[ wrap_config[:result_direction], options, flow_options
|
61
|
+
[ wrap_config[:result_direction], options, flow_options ] # note how we don't return the appended internal args.
|
21
62
|
end
|
22
63
|
end
|
23
64
|
|
24
65
|
Activity = Trailblazer::Circuit::Activity({ id: "task.wrap" }, end: { default: End.new(:default) }) do |act|
|
25
66
|
{
|
26
|
-
act[:Start]
|
27
|
-
|
28
|
-
# MyInject => { Circuit::Right => Trace::CaptureArgs },
|
29
|
-
# Trace::CaptureArgs => { Circuit::Right => Call },
|
30
|
-
Call => { Right => act[:End] },
|
31
|
-
# Trace::CaptureReturn => { Circuit::Right => Output },
|
32
|
-
# Output => { Circuit::Right => act[:End] }
|
67
|
+
act[:Start] => { Right => Call }, # options from outside
|
68
|
+
Call => { Right => act[:End] },
|
33
69
|
}
|
34
|
-
end
|
35
|
-
|
36
|
-
# Find the respective wrap per task, and run it.
|
37
|
-
class Runner
|
38
|
-
# private flow_options[ :step_runners ]
|
39
|
-
def self.call(task, direction, options, flow_options)
|
40
|
-
# TODO: test this decider!
|
41
|
-
task_wrap = flow_options[:step_runners][task] || flow_options[:step_runners][nil] # DISCUSS: default could be more explicit@
|
42
|
-
|
43
|
-
# we can't pass :runner in here since the Step::Pipeline would call itself again, then.
|
44
|
-
# However, we need the runner in nested activities.
|
45
|
-
wrap_config = { step: task }
|
46
|
-
|
47
|
-
# Call the task_wrap circuit:
|
48
|
-
# |-- Start
|
49
|
-
# |-- Trace.capture_args [optional]
|
50
|
-
# |-- Call (call actual task)
|
51
|
-
# |-- Trace.capture_return [optional]
|
52
|
-
# |-- End
|
53
|
-
# Pass empty flow_options to the task_wrap, so it doesn't infinite-loop.
|
54
|
-
task_wrap.( task_wrap[:Start], options, {}, wrap_config, flow_options ) # all tasks in Wrap have to implement this signature.
|
55
|
-
end
|
56
|
-
end # Runner
|
70
|
+
end # Activity
|
57
71
|
end
|
58
72
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trailblazer-circuit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-06-
|
11
|
+
date: 2017-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|