ntl-orchestra 0.9.3 → 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
- ---
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