trailblazer-activity 0.2.0 → 0.2.1
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 +5 -0
- data/lib/trailblazer/activity.rb +8 -4
- data/lib/trailblazer/activity/trace.rb +6 -25
- data/lib/trailblazer/activity/version.rb +1 -1
- data/lib/trailblazer/activity/wrap.rb +1 -64
- data/lib/trailblazer/context.rb +0 -32
- data/lib/trailblazer/wrap/call_task.rb +19 -0
- data/lib/trailblazer/wrap/inject.rb +32 -0
- data/lib/trailblazer/wrap/runner.rb +48 -0
- data/lib/trailblazer/wrap/trace.rb +27 -0
- data/lib/trailblazer/wrap/variable_mapping.rb +92 -0
- metadata +7 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 81fa1b9e57d3f63ee5ee4b5caadea44250fcdbad
|
|
4
|
+
data.tar.gz: ba3e8fc06d51e146702ac7b6eb6765fe3af6e7ee
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 62291d8bbb37376be5e1c6548c35d7df00a7edf654697ac26ed786d55a2bdf49de6130ad0bcfa3a221ff1dbf30935f9ae6d7f2fbe3d143bd4ae42c52d106b110
|
|
7
|
+
data.tar.gz: 3503a6d13258343169a5eddbcc99fa63a169f493dcde5e42962e03775b97c9f09bb9ed68aaa9891ee13a262539dda4051ac4b7e5895b3f01a93f3b4acdd08184
|
data/CHANGES.md
CHANGED
data/lib/trailblazer/activity.rb
CHANGED
|
@@ -11,9 +11,16 @@ module Trailblazer
|
|
|
11
11
|
require "trailblazer/activity/version"
|
|
12
12
|
require "trailblazer/activity/graph"
|
|
13
13
|
require "trailblazer/activity/subprocess"
|
|
14
|
+
|
|
15
|
+
require "trailblazer/activity/wrap"
|
|
16
|
+
require "trailblazer/wrap/variable_mapping"
|
|
17
|
+
require "trailblazer/wrap/call_task"
|
|
18
|
+
require "trailblazer/wrap/trace"
|
|
19
|
+
require "trailblazer/wrap/inject"
|
|
20
|
+
require "trailblazer/wrap/runner"
|
|
21
|
+
|
|
14
22
|
require "trailblazer/activity/trace"
|
|
15
23
|
require "trailblazer/activity/present"
|
|
16
|
-
require "trailblazer/activity/wrap"
|
|
17
24
|
|
|
18
25
|
# Only way to build an Activity.
|
|
19
26
|
def self.from_wirings(wirings, &block)
|
|
@@ -125,8 +132,5 @@ module Trailblazer
|
|
|
125
132
|
@graph.find_all { |node| node[:_wrapped] == task }.first
|
|
126
133
|
end
|
|
127
134
|
end
|
|
128
|
-
|
|
129
|
-
module Interface
|
|
130
|
-
end
|
|
131
135
|
end
|
|
132
136
|
end
|
|
@@ -36,36 +36,17 @@ module Trailblazer
|
|
|
36
36
|
block.(activity, *args)
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
#
|
|
39
|
+
# Graph insertions for the trace tasks that capture the arguments just before calling the task,
|
|
40
|
+
# and before the TaskWrap is finished.
|
|
41
|
+
#
|
|
42
|
+
# Note that the TaskWrap steps are implemented in Activity::Wrap::Trace.
|
|
40
43
|
def self.wirings
|
|
41
44
|
[
|
|
42
|
-
[ :insert_before!, "task_wrap.call_task", node: [ Trace.method(:capture_args), id: "task_wrap.capture_args" ], outgoing: [ Circuit::Right, {} ], incoming: ->(*) { true } ],
|
|
43
|
-
[ :insert_before!, "End.default",
|
|
45
|
+
[ :insert_before!, "task_wrap.call_task", node: [ Wrap::Trace.method(:capture_args), id: "task_wrap.capture_args" ], outgoing: [ Circuit::Right, {} ], incoming: ->(*) { true } ],
|
|
46
|
+
[ :insert_before!, "End.default", node: [ Wrap::Trace.method(:capture_return), id: "task_wrap.capture_return" ], outgoing: [ Circuit::Right, {} ], incoming: ->(*) { true } ],
|
|
44
47
|
]
|
|
45
48
|
end
|
|
46
49
|
|
|
47
|
-
# def self.capture_args(direction, options, flow_options, wrap_config, original_flow_options)
|
|
48
|
-
def self.capture_args((wrap_config, original_args), **circuit_options)
|
|
49
|
-
(original_options, original_flow_options, _) = original_args[0]
|
|
50
|
-
|
|
51
|
-
original_flow_options[:stack].indent!
|
|
52
|
-
|
|
53
|
-
original_flow_options[:stack] << [ wrap_config[:task], :args, nil, {}, original_flow_options[:introspection] ]
|
|
54
|
-
|
|
55
|
-
[ Circuit::Right, [wrap_config, original_args ], **circuit_options ]
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def self.capture_return((wrap_config, original_args), **circuit_options)
|
|
59
|
-
(original_options, original_flow_options, _) = original_args[0]
|
|
60
|
-
|
|
61
|
-
original_flow_options[:stack] << [ wrap_config[:task], :return, wrap_config[:result_direction], {} ]
|
|
62
|
-
|
|
63
|
-
original_flow_options[:stack].unindent!
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
[ Circuit::Right, [wrap_config, original_args ], **circuit_options ]
|
|
67
|
-
end
|
|
68
|
-
|
|
69
50
|
# Mutable/stateful per design. We want a (global) stack!
|
|
70
51
|
class Stack
|
|
71
52
|
def initialize
|
|
@@ -1,68 +1,5 @@
|
|
|
1
1
|
class Trailblazer::Activity
|
|
2
2
|
module Wrap
|
|
3
|
-
# The runner is passed into Activity#call( runner: Runner ) and is called for every task in the circuit.
|
|
4
|
-
# Its primary job is to actually `call` the task.
|
|
5
|
-
#
|
|
6
|
-
# Here, we extend this, and wrap the task `call` into its own pipeline, so we can add external behavior per task.
|
|
7
|
-
module Runner
|
|
8
|
-
# Runner signature: call( task, direction, options, static_wraps )
|
|
9
|
-
#
|
|
10
|
-
# @api private
|
|
11
|
-
# @interface Runner
|
|
12
|
-
def self.call(task, (options, *args), wrap_runtime: raise, wrap_static: raise, **circuit_options)
|
|
13
|
-
wrap_ctx = { task: task }
|
|
14
|
-
|
|
15
|
-
# this activity is "wrapped around" the actual `task`.
|
|
16
|
-
task_wrap_activity = apply_wirings(task, wrap_static, wrap_runtime)
|
|
17
|
-
|
|
18
|
-
# We save all original args passed into this Runner.call, because we want to return them later after this wrap
|
|
19
|
-
# is finished.
|
|
20
|
-
original_args = [ [options, *args], circuit_options.merge( wrap_runtime: wrap_runtime, wrap_static: wrap_static ) ]
|
|
21
|
-
|
|
22
|
-
# call the wrap for the task.
|
|
23
|
-
wrap_end_signal, ( wrap_ctx, _ ) = task_wrap_activity.(
|
|
24
|
-
[ wrap_ctx, original_args ] # we omit circuit_options here on purpose, so the wrapping activity uses the plain Runner.
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
# don't return the wrap's end signal, but the one from call_task.
|
|
28
|
-
# return all original_args for the next "real" task in the circuit (this includes circuit_options).
|
|
29
|
-
|
|
30
|
-
# raise if wrap_ctx[:result_args][2] != static_wraps
|
|
31
|
-
|
|
32
|
-
# TODO: make circuit ignore all returned but the first
|
|
33
|
-
[ wrap_ctx[:result_direction], wrap_ctx[:result_args] ]
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
private
|
|
37
|
-
|
|
38
|
-
# Compute the task's wrap by applying alterations both static and from runtime.
|
|
39
|
-
#
|
|
40
|
-
# NOTE: this is for performance reasons: we could have only one hash containing everything but that'd mean
|
|
41
|
-
# unnecessary computations at `call`-time since steps might not even be executed.
|
|
42
|
-
def self.apply_wirings(task, wrap_static, wrap_runtime)
|
|
43
|
-
wrap_activity = wrap_static[task] # find static wrap for this specific task, or default wrap activity.
|
|
44
|
-
|
|
45
|
-
# Apply runtime alterations.
|
|
46
|
-
# Grab the additional wirings for the particular `task` from `wrap_runtime` (returns default otherwise).
|
|
47
|
-
wrap_activity = Trailblazer::Activity.merge(wrap_activity, wrap_runtime[task])
|
|
48
|
-
end
|
|
49
|
-
end # Runner
|
|
50
|
-
|
|
51
|
-
# The call_task method implements one default step `Call` in the Wrap::Activity circuit.
|
|
52
|
-
# It calls the actual, wrapped task.
|
|
53
|
-
def self.call_task((wrap_ctx, original_args), **circuit_options)
|
|
54
|
-
task = wrap_ctx[:task]
|
|
55
|
-
|
|
56
|
-
# Call the actual task we're wrapping here.
|
|
57
|
-
puts "~~~~wrap.call: #{task}"
|
|
58
|
-
wrap_ctx[:result_direction], wrap_ctx[:result_args] = task.( *original_args )
|
|
59
|
-
|
|
60
|
-
# DISCUSS: do we want original_args here to be passed on, or the "effective" result_args which are different to original_args now?
|
|
61
|
-
[ Trailblazer::Circuit::Right, [ wrap_ctx, original_args ], **circuit_options ]
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
Call = method(:call_task)
|
|
65
|
-
|
|
66
3
|
# Wrap::Activity is the actual circuit that implements the Task wrap. This circuit is
|
|
67
4
|
# also known as `task_wrap`.
|
|
68
5
|
#
|
|
@@ -86,7 +23,7 @@ class Trailblazer::Activity
|
|
|
86
23
|
Trailblazer::Activity.from_wirings(
|
|
87
24
|
[
|
|
88
25
|
[ :attach!, target: [ Trailblazer::Circuit::End.new(:default), type: :event, id: "End.default" ], edge: [ Trailblazer::Circuit::Right, {} ] ],
|
|
89
|
-
[ :insert_before!, "End.default", node: [
|
|
26
|
+
[ :insert_before!, "End.default", node: [ Wrap.method(:call_task), id: "task_wrap.call_task" ], outgoing: [ Trailblazer::Circuit::Right, {} ], incoming: ->(*) { true } ]
|
|
90
27
|
]
|
|
91
28
|
)
|
|
92
29
|
end
|
data/lib/trailblazer/context.rb
CHANGED
|
@@ -60,38 +60,6 @@ module Trailblazer
|
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
62
|
end
|
|
63
|
-
|
|
64
|
-
# FIXME
|
|
65
|
-
# TODO: rename Context::Hash::Immutable
|
|
66
|
-
class Immutable
|
|
67
|
-
def initialize(hash)
|
|
68
|
-
@hash = hash
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def [](key)
|
|
72
|
-
@hash[key]
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def to_hash # DISCUSS: where do we call this?
|
|
76
|
-
@hash.to_hash # FIXME: should we do this?
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def key?(key)
|
|
80
|
-
@hash.key?(key)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def merge(hash)
|
|
84
|
-
@hash.merge(hash)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def keys
|
|
88
|
-
@hash.keys
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
# DISCUSS: raise in #[]=
|
|
92
|
-
# each
|
|
93
|
-
# TODO: Skill could inherit
|
|
94
|
-
end
|
|
95
63
|
end
|
|
96
64
|
|
|
97
65
|
def self.Context(wrapped_options, mutable_options={})
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class Trailblazer::Activity
|
|
2
|
+
module Wrap
|
|
3
|
+
# TaskWrap step that calls the actual wrapped task and passes all `original_args` to it.
|
|
4
|
+
#
|
|
5
|
+
# It writes to wrap_ctx[:result_direction], wrap_ctx[:result_args]
|
|
6
|
+
def self.call_task((wrap_ctx, original_args), **circuit_options)
|
|
7
|
+
task = wrap_ctx[:task]
|
|
8
|
+
|
|
9
|
+
# Call the actual task we're wrapping here.
|
|
10
|
+
puts "~~~~wrap.call: #{task}"
|
|
11
|
+
result_direction, result_args = task.( *original_args ) # we lose :exec_context here.
|
|
12
|
+
|
|
13
|
+
# DISCUSS: do we want original_args here to be passed on, or the "effective" result_args which are different to original_args now?
|
|
14
|
+
wrap_ctx = wrap_ctx.merge( result_direction: result_direction, result_args: result_args )
|
|
15
|
+
|
|
16
|
+
[ Trailblazer::Circuit::Right, [ wrap_ctx, original_args ], **circuit_options ]
|
|
17
|
+
end
|
|
18
|
+
end # Wrap
|
|
19
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
class Trailblazer::Activity
|
|
2
|
+
module Wrap
|
|
3
|
+
module Inject
|
|
4
|
+
# Returns an Alteration wirings that, when applied, inserts the {ReverseMergeDefaults} task
|
|
5
|
+
# before the {Wrap::Call} task. This is meant for macros and steps that accept a dependency
|
|
6
|
+
# injection but need a default parameter to be set if not injected.
|
|
7
|
+
# @returns Alteration
|
|
8
|
+
def self.Defaults(default_dependencies)
|
|
9
|
+
[
|
|
10
|
+
[ :insert_before!, "task_wrap.call_task", node: [ ReverseMergeDefaults.new( default_dependencies ), id: "ReverseMergeDefaults#{default_dependencies}" ], incoming: Proc.new{ true }, outgoing: [ Trailblazer::Circuit::Right, {} ] ]
|
|
11
|
+
]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# @api private
|
|
15
|
+
# @returns Task
|
|
16
|
+
# @param Hash list of key/value that should be set if not already assigned/set before (or injected from the outside).
|
|
17
|
+
class ReverseMergeDefaults
|
|
18
|
+
def initialize(defaults)
|
|
19
|
+
@defaults = defaults
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def call((wrap_ctx, original_args), **circuit_options)
|
|
23
|
+
ctx = original_args[0][0]
|
|
24
|
+
|
|
25
|
+
@defaults.each { |k, v| ctx[k] ||= v }
|
|
26
|
+
|
|
27
|
+
[ Trailblazer::Circuit::Right, [wrap_ctx, original_args] ]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end # Inject
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
class Trailblazer::Activity
|
|
2
|
+
module Wrap
|
|
3
|
+
# The runner is passed into Activity#call( runner: Runner ) and is called for every task in the circuit.
|
|
4
|
+
# It runs the TaskWrap per task.
|
|
5
|
+
#
|
|
6
|
+
# (wrap_ctx, original_args), **wrap_circuit_options
|
|
7
|
+
module Runner
|
|
8
|
+
# Runner signature: call( task, direction, options, static_wraps )
|
|
9
|
+
#
|
|
10
|
+
# @api private
|
|
11
|
+
# @interface Runner
|
|
12
|
+
def self.call(task, args, wrap_runtime: raise, wrap_static: raise, **circuit_options)
|
|
13
|
+
wrap_ctx = { task: task }
|
|
14
|
+
|
|
15
|
+
# this activity is "wrapped around" the actual `task`.
|
|
16
|
+
task_wrap_activity = apply_wirings(task, wrap_static, wrap_runtime)
|
|
17
|
+
|
|
18
|
+
# We save all original args passed into this Runner.call, because we want to return them later after this wrap
|
|
19
|
+
# is finished.
|
|
20
|
+
original_args = [ args, circuit_options.merge( wrap_runtime: wrap_runtime, wrap_static: wrap_static ) ]
|
|
21
|
+
|
|
22
|
+
# call the wrap {Activity} around the task.
|
|
23
|
+
wrap_end_signal, ( wrap_ctx, _ ) = task_wrap_activity.(
|
|
24
|
+
[ wrap_ctx, original_args ] # we omit circuit_options here on purpose, so the wrapping activity uses the default, plain Runner.
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# don't return the wrap's end signal, but the one from call_task.
|
|
28
|
+
# return all original_args for the next "real" task in the circuit (this includes circuit_options).
|
|
29
|
+
|
|
30
|
+
[ wrap_ctx[:result_direction], wrap_ctx[:result_args] ]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
# Compute the task's wrap by applying alterations both static and from runtime.
|
|
36
|
+
#
|
|
37
|
+
# NOTE: this is for performance reasons: we could have only one hash containing everything but that'd mean
|
|
38
|
+
# unnecessary computations at `call`-time since steps might not even be executed.
|
|
39
|
+
def self.apply_wirings(task, wrap_static, wrap_runtime)
|
|
40
|
+
wrap_activity = wrap_static[task] # find static wrap for this specific task, or default wrap activity.
|
|
41
|
+
|
|
42
|
+
# Apply runtime alterations.
|
|
43
|
+
# Grab the additional wirings for the particular `task` from `wrap_runtime` (returns default otherwise).
|
|
44
|
+
wrap_activity = Trailblazer::Activity.merge(wrap_activity, wrap_runtime[task])
|
|
45
|
+
end
|
|
46
|
+
end # Runner
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
class Trailblazer::Activity
|
|
2
|
+
module Wrap
|
|
3
|
+
module Trace
|
|
4
|
+
# def self.capture_args(direction, options, flow_options, wrap_config, original_flow_options)
|
|
5
|
+
def self.capture_args((wrap_config, original_args), **circuit_options)
|
|
6
|
+
(original_options, original_flow_options, _) = original_args[0]
|
|
7
|
+
|
|
8
|
+
original_flow_options[:stack].indent!
|
|
9
|
+
|
|
10
|
+
original_flow_options[:stack] << [ wrap_config[:task], :args, nil, {}, original_flow_options[:introspection] ]
|
|
11
|
+
|
|
12
|
+
[ Trailblazer::Circuit::Right, [wrap_config, original_args], **circuit_options ]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.capture_return((wrap_config, original_args), **circuit_options)
|
|
16
|
+
(original_options, original_flow_options, _) = original_args[0]
|
|
17
|
+
|
|
18
|
+
original_flow_options[:stack] << [ wrap_config[:task], :return, wrap_config[:result_direction], {} ]
|
|
19
|
+
|
|
20
|
+
original_flow_options[:stack].unindent!
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
[ Trailblazer::Circuit::Right, [wrap_config, original_args], **circuit_options ]
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
class Trailblazer::Activity
|
|
2
|
+
module Wrap
|
|
3
|
+
# TaskWrap step to compute the incoming {Context} for the wrapped task.
|
|
4
|
+
# This allows renaming, filtering, hiding, of the options passed into the wrapped task.
|
|
5
|
+
#
|
|
6
|
+
# Both Input and Output are typically to be added before and after task_wrap.call_task.
|
|
7
|
+
#
|
|
8
|
+
# @note Assumption: we always have :input _and_ :output, where :input produces a Context and :output decomposes it.
|
|
9
|
+
class Input
|
|
10
|
+
def initialize(filter)
|
|
11
|
+
@filter = Trailblazer::Option(filter)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# `original_args` are the actual args passed to the wrapped task: [ [options, ..], circuit_options ]
|
|
15
|
+
#
|
|
16
|
+
def call((wrap_ctx, original_args), **circuit_options)
|
|
17
|
+
# let user compute new ctx for the wrapped task.
|
|
18
|
+
input_ctx = apply_filter(*original_args)
|
|
19
|
+
|
|
20
|
+
# TODO: make this unnecessary.
|
|
21
|
+
# wrap user's hash in Context if it's not one, already (in case user used options.merge).
|
|
22
|
+
# DISCUSS: should we restrict user to .merge and options.Context?
|
|
23
|
+
input_ctx = Trailblazer.Context({}, input_ctx) unless input_ctx.instance_of?(Trailblazer::Context)
|
|
24
|
+
|
|
25
|
+
wrap_ctx = wrap_ctx.merge( vm_original_args: original_args )
|
|
26
|
+
|
|
27
|
+
# decompose the original_args since we want to modify them.
|
|
28
|
+
(original_ctx, original_flow_options), original_circuit_options = original_args
|
|
29
|
+
|
|
30
|
+
# instead of the original Context, pass on the filtered `input_ctx` in the wrap.
|
|
31
|
+
return Trailblazer::Circuit::Right, [ wrap_ctx, [[input_ctx, original_flow_options], original_circuit_options] ]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def apply_filter((original_ctx, original_flow_options), original_circuit_options)
|
|
37
|
+
@filter.( original_ctx, **original_circuit_options )
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# TaskWrap step to compute the outgoing {Context} from the wrapped task.
|
|
42
|
+
# This allows renaming, filtering, hiding, of the options returned from the wrapped task.
|
|
43
|
+
class Output
|
|
44
|
+
def initialize(filter, strategy=CopyMutableToOriginal)
|
|
45
|
+
@filter = Trailblazer::Option(filter)
|
|
46
|
+
@strategy = strategy
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Runs the user filter and replaces the ctx in `wrap_ctx[:result_args]` with the filtered one.
|
|
50
|
+
def call((wrap_ctx, original_args), **circuit_options)
|
|
51
|
+
(original_ctx, original_flow_options), original_circuit_options = original_args
|
|
52
|
+
|
|
53
|
+
returned_ctx, _ = wrap_ctx[:result_args] # this is the context returned from `call`ing the task.
|
|
54
|
+
|
|
55
|
+
# returned_ctx is the Context object from the nested operation. In <=2.1, this might be a completely different one
|
|
56
|
+
# than "ours" we created in Input. We now need to compile a list of all added values. This is time-intensive and should
|
|
57
|
+
# be optimized by removing as many Context creations as possible (e.g. the one adding self[] stuff in Operation.__call__).
|
|
58
|
+
_, mutable_data = returned_ctx.decompose # FIXME: this is a weak assumption. What if the task returns a deeply nested Context?
|
|
59
|
+
|
|
60
|
+
# let user compute the output.
|
|
61
|
+
output = apply_filter(mutable_data, original_flow_options, original_circuit_options)
|
|
62
|
+
|
|
63
|
+
original_ctx = wrap_ctx[:vm_original_args][0][0]
|
|
64
|
+
|
|
65
|
+
new_ctx = @strategy.( original_ctx, output ) # here, we compute the "new" options {Context}.
|
|
66
|
+
|
|
67
|
+
wrap_ctx = wrap_ctx.merge( result_args: [new_ctx, original_flow_options] )
|
|
68
|
+
|
|
69
|
+
# and then pass on the "new" context.
|
|
70
|
+
return Trailblazer::Circuit::Right, [ wrap_ctx, original_args ]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
# @note API not stable
|
|
76
|
+
def apply_filter(mutable_data, original_flow_options, original_circuit_options)
|
|
77
|
+
@filter.(mutable_data, **original_circuit_options)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# "merge" Strategy
|
|
81
|
+
class CopyMutableToOriginal
|
|
82
|
+
# @param original Context
|
|
83
|
+
# @param options Context The object returned from a (nested) {Activity}.
|
|
84
|
+
def self.call(original, mutable)
|
|
85
|
+
mutable.each { |k,v| original[k] = v }
|
|
86
|
+
|
|
87
|
+
original
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end # Wrap
|
|
92
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: trailblazer-activity
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.1
|
|
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-10-
|
|
11
|
+
date: 2017-10-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: hirb
|
|
@@ -108,6 +108,11 @@ files:
|
|
|
108
108
|
- lib/trailblazer/container_chain.rb
|
|
109
109
|
- lib/trailblazer/context.rb
|
|
110
110
|
- lib/trailblazer/option.rb
|
|
111
|
+
- lib/trailblazer/wrap/call_task.rb
|
|
112
|
+
- lib/trailblazer/wrap/inject.rb
|
|
113
|
+
- lib/trailblazer/wrap/runner.rb
|
|
114
|
+
- lib/trailblazer/wrap/trace.rb
|
|
115
|
+
- lib/trailblazer/wrap/variable_mapping.rb
|
|
111
116
|
- trailblazer-activity.gemspec
|
|
112
117
|
homepage: http://trailblazer.to/gems/workflow
|
|
113
118
|
licenses:
|