trailblazer-activity 0.9.1 → 0.9.4

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
  SHA256:
3
- metadata.gz: 943560a813f46719e16777daa7f1b58f93a5871838a6e1593a913ecc5a7475a5
4
- data.tar.gz: 0a4e4286edcb7319f0002d82388dbfa9c7005ed76d214884af91e8290ff86fe3
3
+ metadata.gz: 0b971b7f8960520b05bcc99a2fe0561056d9ec244cf9faeb072e131604e0bc12
4
+ data.tar.gz: ec6e1d2c4b2de4d1edfce435c08029a061df61b1b770ad174c005733238269cb
5
5
  SHA512:
6
- metadata.gz: f754c43ff0f0a815e52b3bb5f80f4962f3c3566262b6f731aed3a1b1237bc73a16824ad68dd795ca5f7f01349030907bba302fb56863de5a2f5d57e0d7b6924f
7
- data.tar.gz: 103a79e48cf54ca69767ae4370cec9810d6d5ca5a2352db28896f6ffd232ca98f426ff87d3b6d748173af97589c211f14347ae59779d0f9e834e0ccc7f6d7852
6
+ metadata.gz: 5de05a662519033f02c6e58595d502e80970b08abe7bd87caa7ff23c6acae6490498453bcf8584b8ea6dcba14ef6f00298b1aeca75c5405f8e281e4d206e44e9
7
+ data.tar.gz: 35c9f6d275c0da422e0597529424f005af4e44a344c63c0ca8595d87a44ad8c474be21c5e9c985d1f1a01b2d1ff0b2020da06edcc29e9871af9c174c1766d7cb
data/CHANGES.md CHANGED
@@ -1,3 +1,15 @@
1
+ # 0.9.4
2
+
3
+ Move some test helpers to `Activity::Testing` to export them to other gems
4
+
5
+ # 0.9.3
6
+
7
+ Remove introspection modules, it'll also be part of the `Dev` tools now.
8
+
9
+ # 0.9.2
10
+
11
+ Remove tracing modules, it'll be part of the `Dev` tools now.
12
+
1
13
  # 0.9.1
2
14
 
3
15
  Use `context-0.9.1`.
@@ -49,10 +49,6 @@ require "trailblazer/activity/task_wrap/runner"
49
49
  require "trailblazer/activity/task_wrap/variable_mapping"
50
50
  require "trailblazer/activity/task_wrap/inject"
51
51
 
52
- require "trailblazer/activity/trace"
53
- require "trailblazer/activity/present"
54
-
55
- require "trailblazer/activity/introspect"
56
52
  require "trailblazer/option"
57
53
  require "trailblazer/context"
58
54
  require "trailblazer/activity/task_builder"
@@ -47,10 +47,85 @@ module Trailblazer
47
47
  end
48
48
 
49
49
  module Assertions
50
+ Activity = Trailblazer::Activity
51
+ Inter = Trailblazer::Activity::Schema::Intermediate
52
+ Schema = Trailblazer::Activity::Schema
53
+ TaskWrap = Trailblazer::Activity::TaskWrap
54
+
55
+ module Implementing
56
+ extend Activity::Testing.def_tasks(:a, :b, :c, :d, :f, :g)
57
+
58
+ Start = Activity::Start.new(semantic: :default)
59
+ Failure = Activity::End(:failure)
60
+ Success = Activity::End(:success)
61
+ end
62
+
50
63
  def Cct(activity)
51
64
  cct = Trailblazer::Developer::Render::Circuit.(activity)
52
65
  end
53
66
 
67
+ # TODO: Remove this once all it's references are removed
68
+ def implementing
69
+ Implementing
70
+ end
71
+
72
+ def flat_activity
73
+ return @_flat_activity if defined?(@_flat_activity)
74
+
75
+ intermediate = Inter.new(
76
+ {
77
+ Inter::TaskRef("Start.default") => [Inter::Out(:success, :B)],
78
+ Inter::TaskRef(:B, additional: true) => [Inter::Out(:success, :C)],
79
+ Inter::TaskRef(:C) => [Inter::Out(:success, "End.success")],
80
+ Inter::TaskRef("End.success", stop_event: true) => [Inter::Out(:success, nil)]
81
+ },
82
+ ["End.success"],
83
+ ["Start.default"], # start
84
+ )
85
+
86
+ implementation = {
87
+ "Start.default" => Schema::Implementation::Task(st = Implementing::Start, [Activity::Output(Activity::Right, :success)], []),
88
+ :B => Schema::Implementation::Task(b = Implementing.method(:b), [Activity::Output(Activity::Right, :success)], []),
89
+ :C => Schema::Implementation::Task(c = Implementing.method(:c), [Activity::Output(Activity::Right, :success)], []),
90
+ "End.success" => Schema::Implementation::Task(_es = Implementing::Success, [Activity::Output(Implementing::Success, :success)], []), # DISCUSS: End has one Output, signal is itself?
91
+ }
92
+
93
+ schema = Inter.(intermediate, implementation)
94
+
95
+ @_flat_activity = Activity.new(schema)
96
+ end
97
+
98
+ def nested_activity
99
+ return @_nested_activity if defined?(@_nested_activity)
100
+
101
+ intermediate = Inter.new(
102
+ {
103
+ Inter::TaskRef("Start.default") => [Inter::Out(:success, :B)],
104
+ Inter::TaskRef(:B, more: true) => [Inter::Out(:success, :D)],
105
+ Inter::TaskRef(:D) => [Inter::Out(:success, :E)],
106
+ Inter::TaskRef(:E) => [Inter::Out(:success, "End.success")],
107
+ Inter::TaskRef("End.success", stop_event: true) => [Inter::Out(:success, nil)]
108
+ },
109
+ ["End.success"],
110
+ ["Start.default"] # start
111
+ )
112
+
113
+ implementation = {
114
+ "Start.default" => Schema::Implementation::Task(st = Implementing::Start, [Activity::Output(Activity::Right, :success)], []),
115
+ :B => Schema::Implementation::Task(b = Implementing.method(:b), [Activity::Output(Activity::Right, :success)], []),
116
+ :D => Schema::Implementation::Task(c = bc, [Activity::Output(Implementing::Success, :success)], []),
117
+ :E => Schema::Implementation::Task(e = Implementing.method(:f), [Activity::Output(Activity::Right, :success)], []),
118
+ "End.success" => Schema::Implementation::Task(_es = Implementing::Success, [Activity::Output(Implementing::Success, :success)], []), # DISCUSS: End has one Output, signal is itself?
119
+ }
120
+
121
+ schema = Inter.(intermediate, implementation)
122
+
123
+ @_nested_activity = Activity.new(schema)
124
+ end
125
+
126
+ alias_method :bc, :flat_activity
127
+ alias_method :bde, :nested_activity
128
+
54
129
  # Tests {:circuit} and {:outputs} fields so far.
55
130
  def assert_process_for(process, *args)
56
131
  semantics, circuit = args[0..-2], args[-1]
@@ -1,7 +1,7 @@
1
1
  module Trailblazer
2
2
  module Version
3
3
  module Activity
4
- VERSION = "0.9.1"
4
+ VERSION = "0.9.4"
5
5
  end
6
6
  end
7
7
  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.9.1
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sutterer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-20 00:00:00.000000000 Z
11
+ date: 2019-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: trailblazer-context
@@ -108,8 +108,6 @@ files:
108
108
  - lib/trailblazer/activity.rb
109
109
  - lib/trailblazer/activity/circuit.rb
110
110
  - lib/trailblazer/activity/config.rb
111
- - lib/trailblazer/activity/introspect.rb
112
- - lib/trailblazer/activity/present.rb
113
111
  - lib/trailblazer/activity/schema.rb
114
112
  - lib/trailblazer/activity/schema/implementation.rb
115
113
  - lib/trailblazer/activity/schema/intermediate.rb
@@ -122,7 +120,6 @@ files:
122
120
  - lib/trailblazer/activity/task_wrap/runner.rb
123
121
  - lib/trailblazer/activity/task_wrap/variable_mapping.rb
124
122
  - lib/trailblazer/activity/testing.rb
125
- - lib/trailblazer/activity/trace.rb
126
123
  - lib/trailblazer/activity/version.rb
127
124
  - trailblazer-activity.gemspec
128
125
  homepage: http://trailblazer.to
@@ -145,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
142
  version: '0'
146
143
  requirements: []
147
144
  rubyforge_project:
148
- rubygems_version: 2.7.6
145
+ rubygems_version: 2.7.3
149
146
  signing_key:
150
147
  specification_version: 4
151
148
  summary: Runtime code for Trailblazer activities.
@@ -1,72 +0,0 @@
1
- module Trailblazer
2
- class Activity
3
- # The Introspect API provides inflections for `Activity` instances.
4
- # It abstracts internals about circuits and provides a convenient API to third-parties such as
5
- # tracing, rendering an activity, or finding particular tasks.
6
- module Introspect
7
- def self.Graph(*args)
8
- Graph.new(*args)
9
- end
10
-
11
- # TODO: order of step/fail/pass in Node would be cool to have
12
-
13
- # @private This API is still under construction.
14
- class Graph
15
- def initialize(activity)
16
- @activity = activity
17
- @schema = activity.to_h or raise
18
- @circuit = @schema[:circuit]
19
- @map = @circuit.to_h[:map]
20
- @configs = @schema[:nodes]
21
- end
22
-
23
- def find(id=nil, &block)
24
- return find_by_id(id) unless block_given?
25
- find_with_block(&block)
26
- end
27
-
28
- def collect(strategy: :circuit, &block)
29
- @map.keys.each_with_index.collect { |task, i| yield find_with_block { |node| node.task==task }, i }
30
- end
31
-
32
- def stop_events
33
- @circuit.to_h[:end_events]
34
- end
35
-
36
- private
37
-
38
- def find_by_id(id)
39
- node = @configs.find { |node| node.id == id } or return
40
- node_for(node)
41
- end
42
-
43
- def find_with_block(&block)
44
- existing = @configs.find { |node| yield Node(node.task, node.id, node.outputs, node.data) } or return
45
-
46
- node_for(existing)
47
- end
48
-
49
- def node_for(node_attributes)
50
- Node(node_attributes.task, node_attributes.id, node_attributes.outputs, outgoings_for(node_attributes), node_attributes.data)
51
- end
52
-
53
- def Node(*args)
54
- Node.new(*args).freeze
55
- end
56
-
57
- Node = Struct.new(:task, :id, :outputs, :outgoings, :data)
58
- Outgoing = Struct.new(:output, :task)
59
-
60
- def outgoings_for(node)
61
- outputs = node.outputs
62
- connections = @map[node.task]
63
-
64
- connections.collect do |signal, target|
65
- output = outputs.find { |out| out.signal == signal }
66
- Outgoing.new(output, target)
67
- end
68
- end
69
- end
70
- end #Introspect
71
- end
72
- end
@@ -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