trailblazer-circuit 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c9e50c60fbd29ee44bc11f122198acec25c02122
4
- data.tar.gz: de1fb71290d6c4a817827bfad946cf739a1d4291
3
+ metadata.gz: d3c9b6666028fb2423dace64b0d84dfd67427e3a
4
+ data.tar.gz: a2ec4fb343197e3c512a0a0bb1c1a924ecdbee57
5
5
  SHA512:
6
- metadata.gz: c8b5ea44e5ca1a618da4c4b4c5130d27700ada1766c621e4753e4d58765995f6799490e3b842f89183ec1ea860704e0c3d55549270cc1a539fab93b5f503269c
7
- data.tar.gz: 0cf6a6dd1cc39496a236eb2d816e360efca4f60d263a0d591a8f799890bc5e29bd3a8a0ccdcf9b89aa04b11071b40cf7aa0b196e6a7d41f2bf1273df2c646747
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: Activity::Wrapped::Runner,
20
- stack: Circuit::Trace::Stack.new,
21
- step_runners: step_runners,
22
- debug: activity.circuit.instance_variable_get(:@name)
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[:step], :args, nil, options.dup, original_flow_options[:debug] ]
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[:step], :return, flow_options[:result_direction], options.dup ]
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,5 +1,5 @@
1
1
  module Trailblazer
2
2
  class Circuit
3
- VERSION = "0.0.4"
3
+ VERSION = "0.0.5"
4
4
  end
5
5
  end
@@ -1,9 +1,52 @@
1
1
  class Trailblazer::Circuit
2
+ # Lingo: task_wrap
2
3
  module Activity::Wrapped
3
- # Input = ->(direction, options, flow_options) { [direction, options, flow_options] }
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[:step]
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, wrap_config, *args ]
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] => { Right => Call }, # options from outside
27
- # Input => { Circuit::Right => Trace::CaptureArgs },
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
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-06 00:00:00.000000000 Z
11
+ date: 2017-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler