ntl-orchestra 0.9.3 → 0.9.4

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 CHANGED
@@ -1,7 +1,7 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 04d7c524d1821f1d2dcaec41a3a567c906b69830
4
- data.tar.gz: 7be0bf35060a1714d0edb8d6489d49f46011ac13
5
- SHA512:
6
- metadata.gz: 82a9d1d61b21cbd09464027b6a72c43fc433979ec851be8906b3f7eb590c7baad62ef200cae5cb21a86ab4a20551c34c744aa801d30601d9d7e2b147fb9a0d89
7
- data.tar.gz: b8101d3196af1ffbb1f7faa578c3f665d76d102395331fcda4242b6b9e0e48cfa5d71976c91cc24f00ecdd3d0a91508733eb4be58b89e587b32df799d5f2f70a
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e96984bfe46ae0b8f9769e7d2a63fcfc2d3efc04
4
+ data.tar.gz: 35665deb648f6be6360f566d4d504b7e609e28d0
5
+ SHA512:
6
+ metadata.gz: 9af68198925832621e1a08a4fb34c2da7881a44aab59f350485c2a4e6845ecdbd2631e089315e392bf5047453ae67a20eaf07bdf5ce3535bf148c4445cfaf646
7
+ data.tar.gz: 99e4ed20368788e954eab33f8bd79ddc7c329cf0fec6ef13fc7fec550fe06b78df1b9362c7f7d5093d21a2b0422bd6c139d49b72a435b871798ca5a000db5f6a
data/README.md CHANGED
@@ -466,14 +466,14 @@ end
466
466
 
467
467
  The arguments passed to `update` will vary based on the event:
468
468
 
469
- | Event | First argument | Second argument |
470
- | ------------------------ | ------------------------------------ | --------------------------------- |
471
- | `:operation_entered` | The name of the operation starting | Input going into the operation |
472
- | `:operation_exited` | The name of the operation finishing | Output of the operation |
473
- | `:step_entered` | The name of the step | Input going into the step |
474
- | `:step_exited` | The name of the step | Output of the step |
475
- | `:error_raised` | The error itself | `nil` |
476
- | `:service_accessed` | The name of the service | Recording of the service call |
469
+ | Event | First argument | Second argument |
470
+ | ------------------------ | ----------------------- | --------------------------------- |
471
+ | `:operation_entered` | The Operation starting | Input going into the operation |
472
+ | `:operation_exited` | The Operation finishing | Output of the operation |
473
+ | `:step_entered` | The Step | Input going into the step |
474
+ | `:step_exited` | The Step | Output of the step |
475
+ | `:error_raised` | The error itself | `nil` |
476
+ | `:service_accessed` | The name of the service | Recording of the service call |
477
477
 
478
478
  All observers attached to the execution of the outer operation will also attach to the inner operation.
479
479
 
@@ -42,6 +42,14 @@ module Orchestra
42
42
  def dependencies
43
43
  [collection, *object_method.dependencies].compact
44
44
  end
45
+
46
+ def name
47
+ if method_name == :execute
48
+ object.name
49
+ else
50
+ "#{object.name}##{method_name}"
51
+ end
52
+ end
45
53
  end
46
54
 
47
55
  class SingletonAdapter < ObjectAdapter
@@ -57,15 +57,15 @@ module Orchestra
57
57
  end
58
58
 
59
59
  def build_object_step object, args
60
- name = object_name object
61
60
  step = ObjectAdapter.build_step object, args
61
+ name = object_name step.adapter
62
62
  [name, step]
63
63
  end
64
64
 
65
65
  private
66
66
 
67
67
  def object_name object
68
- object.name and Util.to_snake_case Util.demodulize object.name
68
+ object.name and Util.to_snake_case object.name
69
69
  end
70
70
  end
71
71
 
@@ -91,8 +91,9 @@ module Orchestra
91
91
  nil
92
92
  end
93
93
 
94
- def result name = nil, &block
95
- step = @builder.add_step name, &block
94
+ def result *args, &block
95
+ args << nil if args.empty?
96
+ step = @builder.add_step *args, &block
96
97
  name ||= step.provisions.fetch 0
97
98
  self.result = name
98
99
  end
@@ -2,13 +2,16 @@ module Orchestra
2
2
  module Execution
3
3
  extend self
4
4
 
5
- def start_operation *args
6
- Operation.new *args
5
+ def build operation, conductor, input = {}
6
+ run_list = RunList.build operation.steps, operation.result, input.keys
7
+ node = Node.new run_list, operation.name, input
8
+ Operation.new conductor, run_list, input, node
7
9
  end
8
10
 
9
11
  def execute_step step, input
10
- operation_execution = Operation.new Conductor.new, {}, input
11
- Step.execute step, 'anonymous', operation_execution
12
+ node = Node.new step, 'anonymous', input
13
+ operation_execution = Operation.new Conductor.new, {}, input, node
14
+ Step.execute step, node.name, operation_execution
12
15
  end
13
16
 
14
17
  class Operation
@@ -18,24 +21,32 @@ module Orchestra
18
21
  def_delegators :@run_list, :provisions, :dependencies,
19
22
  :optional_dependencies, :required_dependencies
20
23
 
21
- attr :conductor, :input, :state, :registry, :run_list
24
+ attr :conductor, :input, :node, :registry, :run_list, :state
22
25
 
23
- def initialize conductor, run_list, input
26
+ def initialize conductor, run_list, input, node
24
27
  @conductor = conductor
25
28
  @input = input.dup
29
+ @node = node
26
30
  @run_list = run_list
27
31
  @registry = conductor.build_registry self
28
32
  @state = registry.merge input
29
33
  end
30
34
 
31
35
  def execute
36
+ publish :operation_entered, node, node.input if node
32
37
  ensure_inputs_are_present!
33
38
  run_list.each do |name, step| process name, step end
39
+ publish :operation_exited, node, output if node
40
+ output
34
41
  rescue => error
35
42
  publish :error_raised, error
36
43
  raise error
37
44
  end
38
45
 
46
+ def output
47
+ state.fetch run_list.result
48
+ end
49
+
39
50
  def process name, step
40
51
  output = Step.execute step, name, self
41
52
  state.merge! output
@@ -47,10 +58,6 @@ module Orchestra
47
58
  raise MissingInputError.new missing_input unless missing_input.empty?
48
59
  end
49
60
 
50
- def extract_result result
51
- state.fetch result
52
- end
53
-
54
61
  def publish event, *payload
55
62
  changed
56
63
  notify_observers event, *payload
@@ -78,7 +85,7 @@ module Orchestra
78
85
  instance
79
86
  end
80
87
 
81
- attr :context, :name, :operation_execution, :step
88
+ attr :context, :name, :node, :operation_execution, :step
82
89
 
83
90
  def initialize step, name, operation_execution
84
91
  @name = name
@@ -88,9 +95,10 @@ module Orchestra
88
95
  end
89
96
 
90
97
  def execute
91
- operation_execution.publish :step_entered, name, input
98
+ @node = Node.new step, name, input
99
+ operation_execution.publish :step_entered, node, node.input
92
100
  output = step.process invoke
93
- operation_execution.publish :step_exited, name, output
101
+ operation_execution.publish :step_exited, node, output
94
102
  output
95
103
  end
96
104
 
@@ -108,6 +116,10 @@ module Orchestra
108
116
  def build_context
109
117
  step.build_context operation_execution.state
110
118
  end
119
+
120
+ def to_node
121
+ Node.new step, name
122
+ end
111
123
  end
112
124
 
113
125
  class CollectionStep < Step
@@ -0,0 +1,52 @@
1
+ module Orchestra
2
+ # Reader object to expose operations and steps to the outside world
3
+ class Node
4
+ attr :input, :name
5
+
6
+ extend Forwardable
7
+
8
+ def_delegators :@node, :provisions, :dependencies, :optional_dependencies,
9
+ :required_dependencies
10
+
11
+ def initialize step_or_operation, name, input
12
+ @name = name
13
+ @node = step_or_operation
14
+ @input = format_input input
15
+ freeze
16
+ end
17
+
18
+ def to_h
19
+ {
20
+ dependencies: dependencies,
21
+ input: input,
22
+ name: name,
23
+ optional_dependencies: optional_dependencies,
24
+ provisions: provisions,
25
+ required_dependencies: required_dependencies,
26
+ }
27
+ end
28
+
29
+ def inspect
30
+ params = to_h.each_with_object [] do |(key, val), list|
31
+ list << "#{key}=#{val.inspect}"
32
+ end
33
+ "#<Orchestra::Node #{params.join ', '}>"
34
+ end
35
+
36
+ def operation?
37
+ @node.is_a? Operation
38
+ end
39
+
40
+ def step?
41
+ not operation?
42
+ end
43
+
44
+ private
45
+
46
+ def format_input input
47
+ @node.dependencies.each_with_object Hash.new do |dep, hsh|
48
+ hsh[dep] = input[dep] if input.has_key? dep
49
+ end
50
+ end
51
+ end
52
+ end
@@ -27,23 +27,19 @@ module Orchestra
27
27
  output.select do |key, _| key = result end
28
28
  end
29
29
 
30
+ def execute *args, &block
31
+ execution = start_execution *args, &block
32
+ output = execution.execute
33
+ @command ? nil : output
34
+ end
35
+
30
36
  def start_execution *args
31
37
  conductor, input = extract_args args
32
- run_list = RunList.build steps, result, input.keys
33
- execution = Execution.start_operation conductor, run_list, input
38
+ execution = Execution.build self, conductor, input
34
39
  yield execution if block_given?
35
- execution.publish :operation_entered, name, input
36
40
  execution
37
41
  end
38
42
 
39
- def execute *args, &block
40
- execution = start_execution *args, &block
41
- execution.execute
42
- output = execution.extract_result result
43
- execution.publish :operation_exited, name, output
44
- @command ? nil : output
45
- end
46
-
47
43
  def command?
48
44
  @command ? true : false
49
45
  end
@@ -6,9 +6,12 @@ module Orchestra
6
6
  builder.build
7
7
  end
8
8
 
9
+ attr :result
10
+
9
11
  include Enumerable
10
12
 
11
- def initialize steps
13
+ def initialize steps, result
14
+ @result = result
12
15
  @steps = steps
13
16
  @steps.freeze
14
17
  freeze
@@ -84,7 +87,7 @@ module Orchestra
84
87
  def build
85
88
  sort!
86
89
  prune!
87
- RunList.new @steps_hash
90
+ RunList.new @steps_hash, @result
88
91
  end
89
92
 
90
93
  def sort!
@@ -1,3 +1,3 @@
1
1
  module Orchestra
2
- VERSION = "0.9.3" unless defined? VERSION
2
+ VERSION = "0.9.4" unless defined? VERSION
3
3
  end
@@ -14,29 +14,29 @@ class TelemetryRecorder
14
14
  @embedded
15
15
  end
16
16
 
17
- def handle_operation_entered operation_name, input
17
+ def handle_operation_entered operation, input
18
18
  return if embedded?
19
19
  @steps = Hash.new do |hsh, key| hsh[key] = {} end
20
20
  @store.update(
21
21
  :input => input,
22
22
  :movements => @steps,
23
- :operation_name => operation_name,
23
+ :operation_name => operation.name,
24
24
  :service_calls => [],
25
25
  )
26
26
  @embedded = true
27
27
  end
28
28
 
29
- def handle_operation_exited operation_name, output
29
+ def handle_operation_exited operation, output
30
30
  @store[:output] = output
31
31
  @embedded = false
32
32
  end
33
33
 
34
- def handle_step_entered name, input
35
- @steps[name][:input] = input
34
+ def handle_step_entered step, input
35
+ @steps[step.name][:input] = input
36
36
  end
37
37
 
38
- def handle_step_exited name, output
39
- @steps[name][:output] = output
38
+ def handle_step_exited step, output
39
+ @steps[step.name][:output] = output
40
40
  end
41
41
 
42
42
  def handle_error_raised error
@@ -0,0 +1,10 @@
1
+ class NodeTest < Minitest::Test
2
+ def test_inspect
3
+ node = Orchestra::Node.new Examples::FizzBuzz, "Examples::FizzBuzz", {}
4
+
5
+ assert_equal(
6
+ "#<Orchestra::Node dependencies=[:array, :fizzbuzz, :io, :up_to], input={}, name=\"Examples::FizzBuzz\", optional_dependencies=[], provisions=[:array, :fizzbuzz, :print], required_dependencies=[:io, :up_to]>",
7
+ node.inspect,
8
+ )
9
+ end
10
+ end
@@ -27,13 +27,7 @@ class ObjectAdapterTest < Minitest::Test
27
27
  end
28
28
 
29
29
  def test_executing_an_operation_with_integrated_objects
30
- operation = Orchestra::Operation.new do
31
- step Splitter, :provides => :words
32
- step Upcaser, :iterates_over => :words, :provides => :upcased_words, :method => :call
33
- step Bolder, :iterates_over => :upcased_words, :provides => :bolded_words, :method => :call
34
- step Joiner, :method => :join
35
- self.result = :joiner
36
- end
30
+ operation = integrated_objects_operation
37
31
 
38
32
  result = Orchestra.execute(
39
33
  operation,
@@ -60,10 +54,36 @@ class ObjectAdapterTest < Minitest::Test
60
54
  )
61
55
  end
62
56
 
57
+ def test_name_includes_method_when_not_using_execute
58
+ assert_equal(
59
+ %i(
60
+ object_adapter_test/splitter
61
+ object_adapter_test/upcaser#call
62
+ object_adapter_test/bolder#call
63
+ object_adapter_test/joiner#join
64
+ ),
65
+ integrated_objects_operation.steps.keys,
66
+ )
67
+ end
68
+
69
+ private
70
+
71
+ def integrated_objects_operation
72
+ Orchestra::Operation.new do
73
+ step Splitter, :provides => :words
74
+ step Upcaser, :iterates_over => :words, :provides => :upcased_words, :method => :call
75
+ step Bolder, :iterates_over => :upcased_words, :provides => :bolded_words, :method => :call
76
+ result Joiner, :method => :join
77
+ end
78
+ end
79
+
63
80
  module Splitter
64
- def self.execute sentence
81
+ extend self
82
+
83
+ def execute sentence
65
84
  sentence.split %r{[[:space:]]+}
66
85
  end
86
+ alias_method :call, :execute
67
87
  end
68
88
 
69
89
  class Upcaser
metadata CHANGED
@@ -1,67 +1,81 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ntl-orchestra
3
- version: !ruby/object:Gem::Version
4
- version: 0.9.3
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.4
5
5
  platform: ruby
6
- authors:
6
+ authors:
7
7
  - ntl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
-
12
- date: 2015-01-08 00:00:00 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- requirement: &id001 !ruby/object:Gem::Requirement
16
- requirements:
17
- - &id003
18
- - ">="
19
- - !ruby/object:Gem::Version
20
- version: "0"
11
+ date: 2015-01-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
21
14
  name: invokr
22
- prerelease: false
23
- version_requirements: *id001
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
24
20
  type: :runtime
25
- - !ruby/object:Gem::Dependency
26
- requirement: &id002 !ruby/object:Gem::Requirement
27
- requirements:
28
- - - ~>
29
- - !ruby/object:Gem::Version
30
- version: "1.6"
31
- name: bundler
32
21
  prerelease: false
33
- version_requirements: *id002
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
34
  type: :development
35
- - !ruby/object:Gem::Dependency
36
- requirement: &id004 !ruby/object:Gem::Requirement
37
- requirements:
38
- - *id003
39
- name: pry
40
35
  prerelease: false
41
- version_requirements: *id004
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
42
48
  type: :development
43
- - !ruby/object:Gem::Dependency
44
- requirement: &id005 !ruby/object:Gem::Requirement
45
- requirements:
46
- - - ~>
47
- - !ruby/object:Gem::Version
48
- version: "10.0"
49
- name: rake
50
49
  prerelease: false
51
- version_requirements: *id005
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
52
62
  type: :development
53
- description: Orchestra is an orchestration framework for designing complex operations in an object oriented fashion.
54
- email:
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ description: Orchestra is an orchestration framework for designing complex operations
70
+ in an object oriented fashion.
71
+ email:
55
72
  - nathanladd+github@gmail.com
56
73
  executables: []
57
-
58
74
  extensions: []
59
-
60
75
  extra_rdoc_files: []
61
-
62
- files:
63
- - .gitignore
64
- - .travis.yml
76
+ files:
77
+ - ".gitignore"
78
+ - ".travis.yml"
65
79
  - Gemfile
66
80
  - LICENSE.txt
67
81
  - README.md
@@ -76,6 +90,7 @@ files:
76
90
  - lib/orchestra/dsl/steps.rb
77
91
  - lib/orchestra/errors.rb
78
92
  - lib/orchestra/execution.rb
93
+ - lib/orchestra/node.rb
79
94
  - lib/orchestra/operation.rb
80
95
  - lib/orchestra/recording.rb
81
96
  - lib/orchestra/recording/playback.rb
@@ -97,6 +112,7 @@ files:
97
112
  - test/test_helper.rb
98
113
  - test/unit/conductor_test.rb
99
114
  - test/unit/dsl_test.rb
115
+ - test/unit/node_test.rb
100
116
  - test/unit/object_adapter_test.rb
101
117
  - test/unit/operation_test.rb
102
118
  - test/unit/run_list_test.rb
@@ -105,29 +121,30 @@ files:
105
121
  - test/unit/util_test.rb
106
122
  - tmp/.keep
107
123
  homepage: https://github.com/ntl/orchestra
108
- licenses:
124
+ licenses:
109
125
  - MIT
110
126
  metadata: {}
111
-
112
127
  post_install_message:
113
128
  rdoc_options: []
114
-
115
- require_paths:
129
+ require_paths:
116
130
  - lib
117
- required_ruby_version: !ruby/object:Gem::Requirement
118
- requirements:
119
- - *id003
120
- required_rubygems_version: !ruby/object:Gem::Requirement
121
- requirements:
122
- - *id003
131
+ required_ruby_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
123
141
  requirements: []
124
-
125
142
  rubyforge_project:
126
- rubygems_version: 2.4.2
143
+ rubygems_version: 2.4.5
127
144
  signing_key:
128
145
  specification_version: 4
129
146
  summary: Orchestrate complex operations with ease.
130
- test_files:
147
+ test_files:
131
148
  - test/examples/fizz_buzz.rb
132
149
  - test/examples/invitation_service.rb
133
150
  - test/integration/multithreading_test.rb
@@ -139,6 +156,7 @@ test_files:
139
156
  - test/test_helper.rb
140
157
  - test/unit/conductor_test.rb
141
158
  - test/unit/dsl_test.rb
159
+ - test/unit/node_test.rb
142
160
  - test/unit/object_adapter_test.rb
143
161
  - test/unit/operation_test.rb
144
162
  - test/unit/run_list_test.rb