gilmour 0.4.4 → 0.4.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: 7a61b1be06598f3e75a8a9ba987f972258955edd
4
- data.tar.gz: 8198bf46a1945c319c95002a7f0885eb66aa961c
3
+ metadata.gz: 2f60416d0af8de59564c01a5580ee0a40df3772d
4
+ data.tar.gz: 2055fa3c380a7524d528c5e079c671e70f4acbfc
5
5
  SHA512:
6
- metadata.gz: 06e5a201e77837513442296ae6f2d116893f6cfbe4aa84bafeaaab468b56ca89e3f7a5fe91dc730932ad72ad2e8014c5d27e5cc96a8f6ca156dd56aff39d07cd
7
- data.tar.gz: 01e1a704c10fd57fc3c29304d24e8f09699ccd28b1dfe2a2d1d870878977f0feb0eadc03bd64dfb7d43bcc736beb85214da9d9a4ce5f5e9aefde74ee12149a1d
6
+ metadata.gz: 6225255b7c13937b8c0cf83def803eb8827908a8b1580a838d3617b2d3845b743b008294736fb3890af2c090300748d30e4797c8f69de5ee86dfc0ccdf61224f
7
+ data.tar.gz: c6b4e8128620579b15939d0fe6ca3be4d377acc513495bc2c692e1e2650a6c7c83f7d9942eb9bd90f0dcd36ed74a54e7bbf50a868f4a1dbd79b4f6eec2a8939b
data/.gitignore CHANGED
@@ -3,3 +3,4 @@
3
3
  *.swp
4
4
  *.gem
5
5
 
6
+ doc
data/README.md CHANGED
@@ -30,6 +30,7 @@ Microservices increase the granularity of our services oriented architectures. B
30
30
  * Composition: `cmd1 | cmd2 | cmd2`
31
31
  * AndAnd: `cmd1 && cmd2 && cmd3`
32
32
  * Batch: `cmd1; cmd2; cmd3 > out` or `(cmd1; cmd2; cmd3) > out`
33
+ * Parallel: This runs stages in parallel call the callback when all are done. The data passed to the callback is an array of {:data, :code} hashes in no particular order. The code is the highest error code from the array.
33
34
 
34
35
  Also, you should be able to use these methods of composition in any combination and also in a nexted manner - `(cmd1 | cmd2) && cmd3`. Gilmour enables you to do just that. See `examples/composition.rb`.
35
36
 
@@ -76,9 +76,9 @@ batch.execute do |data, code|
76
76
  end
77
77
  batch_waiter.wait
78
78
 
79
- batch_record = gilmour.batch([{topic: 'one'}, {topic: 'badtwo'},
80
- {topic: 'three', message: {'anotherthree' => 'anotherthree'}}],
81
- true) # true will record all responses in an array
79
+ batch_record = gilmour.batch([{topic: 'one'}, {topic: 'badtwo'},
80
+ {topic: 'three', message: {'anotherthree' => 'anotherthree'}}
81
+ ]).with_recorder # with_recorder will record all responses in an array
82
82
  batch_record_waiter = Gilmour::Waiter.new
83
83
  batch_record.execute do |data, code|
84
84
  puts "\nbatch with record:"
@@ -87,6 +87,13 @@ batch_record.execute do |data, code|
87
87
  end
88
88
  batch_record_waiter.wait
89
89
 
90
+ parallel = gilmour.parallel([{topic: 'one'}, {topic: 'badtwo'}])
91
+ parallel.execute do |data, code|
92
+ puts "\nparallel:"
93
+ puts code
94
+ data.each { |d| puts d }
95
+ end
96
+
90
97
  t_andand = gilmour.andand([{topic: 'one'}, {topic: 'two'}])
91
98
  # Use the above composition inside another
92
99
  compose = gilmour.compose([t_andand, {topic: 'three'}])
data/gilmour.gemspec CHANGED
@@ -17,7 +17,6 @@ Gem::Specification.new do |s|
17
17
  s.add_dependency "mash"
18
18
  s.add_dependency "redis"
19
19
  s.add_dependency "gilmour-em-hiredis"
20
- s.add_dependency "amqp"
21
20
 
22
21
  s.files = `git ls-files`.split("\n")
23
22
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -145,7 +145,11 @@ module Gilmour
145
145
  end
146
146
  end
147
147
 
148
- def response_handler(sender, payload) #:nodoc:
148
+ def response_handler(sender, payload)
149
+ EM.defer { _response_handler(sender, payload) }
150
+ end
151
+
152
+ def _response_handler(sender, payload) #:nodoc:
149
153
  data, code, _ = Gilmour::Protocol.parse_response(payload)
150
154
  handler = @response_handlers.delete(sender)
151
155
  @subscriber.unsubscribe(sender)
@@ -25,7 +25,11 @@ module Gilmour
25
25
 
26
26
  def execute(data = {}, &blk)
27
27
  if @spec.kind_of?(Proc)
28
- res = @spec.call(data)
28
+ begin
29
+ res = @spec.call(data)
30
+ rescue => e
31
+ code = 500
32
+ end
29
33
  code = res ? 200 : 500
30
34
  blk.call(res, code)
31
35
  else
@@ -114,8 +118,8 @@ module Gilmour
114
118
  # any kind of composition itself, allowing the creation of
115
119
  # nested compositions. See examples in the source code.
116
120
  #
117
- def compose(spec)
118
- Compose.new(self, spec)
121
+ def compose(*spec)
122
+ Compose.new(self, spec.flatten)
119
123
  end
120
124
 
121
125
  class AndAnd < Pipeline
@@ -142,16 +146,20 @@ module Gilmour
142
146
  # It is roughly equivalent to the unix construct
143
147
  # cmd1 && cmd2 && cmd3
144
148
 
145
- def andand(spec)
146
- AndAnd.new(self, spec)
149
+ def andand(*spec)
150
+ AndAnd.new(self, spec.flatten)
147
151
  end
148
152
 
149
153
  class Batch < Pipeline
150
- def initialize(backend, spec, record=false) #:nodoc:
154
+ def initialize(backend, spec) #:nodoc:
151
155
  super(backend, spec)
152
- @record = record
156
+ @record = false
153
157
  end
154
158
 
159
+ def with_recorder(record=true)
160
+ @record = record
161
+ self
162
+ end
155
163
  # Execute the batch pipeline. This pipeline ignores all errors
156
164
  # step is passed to block.
157
165
  # See the documentation of the #batch method for more details
@@ -183,8 +191,45 @@ module Gilmour
183
191
  # +record+:: If this is false, only the output of the last step
184
192
  # is passed to the block passed to execute. If true, all outputs
185
193
  # are collected in an array and passed to the block
186
- def batch(spec, record=false)
187
- Batch.new(self, spec, record)
194
+ def batch(*spec)
195
+ Batch.new(self, spec.flatten)
196
+ end
197
+
198
+ class Parallel < Pipeline
199
+ def initialize(backend, spec) #:nodoc:
200
+ super(backend, spec)
201
+ end
202
+
203
+ # Execute the batch pipeline. This pipeline ignores all errors
204
+ # step is passed to block.
205
+ # See the documentation of the #batch method for more details
206
+ def execute(data=nil, &blk)
207
+ results = []
208
+ blk.call(nil, nil) if pipeline.empty?
209
+ waiters = []
210
+ pipeline.each do |p|
211
+ waiter = Gilmour::Waiter.new
212
+ waiters << waiter
213
+ p.execute do |d, c|
214
+ results << {data: d, code: c}
215
+ waiter.signal
216
+ end
217
+ end
218
+ waiters.each(&:wait)
219
+ code = results.map { |r| r[:code] }.max
220
+ blk.call(results, code)
221
+ end
222
+ end
223
+
224
+ def parallel(*spec)
225
+ Parallel.new(self, spec.flatten)
226
+ end
227
+
228
+ def sync(*spec, &blk)
229
+ Parallel.new(self, spec.flatten).execute do |_res, code|
230
+ res = _res.size == 1 ? _res.first[:data] : _res
231
+ blk.call(res, code)
232
+ end
188
233
  end
189
234
  end
190
235
  end
@@ -29,6 +29,7 @@ module Gilmour
29
29
 
30
30
  attr_reader :logger
31
31
  attr_reader :request
32
+ attr_reader :backend
32
33
 
33
34
  def child_logger(writer) #:nodoc:
34
35
  logger = Logger.new(STDERR)
@@ -131,6 +131,23 @@ describe 'Pipelines' do
131
131
  end
132
132
  end
133
133
 
134
+ context 'Parallel' do
135
+ Given(:parallel) {
136
+ gilmour.parallel([{topic: 'one'}, {topic: 'badtwo'},
137
+ {topic: 'three', message: {'anotherthree' => 'anotherthree'}}])
138
+ }
139
+ Then {
140
+ done = false
141
+ parallel.execute do |data, code|
142
+ expect(data).to be_kind_of(Array)
143
+ expect(data.size).to eq(3)
144
+ expect(code).to eq(500)
145
+ done = true
146
+ end
147
+ expect(done).to eq(true)
148
+ }
149
+ end
150
+
134
151
  context 'Batch' do
135
152
  context 'Without record' do
136
153
  Given(:batch) {
@@ -158,8 +175,8 @@ describe 'Pipelines' do
158
175
  context 'With record' do
159
176
  Given(:batchrecord) {
160
177
  gilmour.batch([{topic: 'one'}, {topic: 'badtwo'},
161
- {topic: 'three', message: {'anotherthree' => 'anotherthree'}}],
162
- true)
178
+ {topic: 'three', message: {'anotherthree' => 'anotherthree'}}
179
+ ]).with_recorder
163
180
  }
164
181
  Then {
165
182
  waiter = Waiter.new
@@ -183,8 +200,13 @@ describe 'Pipelines' do
183
200
  Given(:andand) {
184
201
  gilmour.andand([{topic: 'one'}, {topic: 'two'}])
185
202
  }
203
+ Given(:parallel) {
204
+ gilmour.compose([gilmour.parallel([{topic: 'one'}, {topic: 'two'}]),
205
+ ->(d) { d.reduce({}) { |m, r| m.merge(r[:data]) } }]
206
+ )
207
+ }
186
208
  Given(:compose) {
187
- gilmour.compose([andand, {topic: 'three'}])
209
+ gilmour.compose([andand, parallel, {topic: 'three'}])
188
210
  }
189
211
  Then {
190
212
  waiter = Waiter.new
@@ -195,11 +217,11 @@ describe 'Pipelines' do
195
217
  waiter.signal
196
218
  end
197
219
  waiter.wait
198
- expect(data.keys.size).to eq(2)
199
- ['two', 'three'].each do |k|
220
+ expect(code).to eq(200)
221
+ expect(data.keys.size).to eq(3)
222
+ ['one', 'two', 'three'].each do |k|
200
223
  expect(data.has_key?(k)).to be_truthy
201
224
  end
202
- expect(code).to eq(200)
203
225
  }
204
226
  end
205
227
  end
@@ -11,7 +11,6 @@ def install_test_subscriber
11
11
  TestReplier.callback do |topic, data|
12
12
  @topic = topic
13
13
  @data = data
14
- $stderr.puts "Got callback #{topic}, #{data}"
15
14
  waiter.signal
16
15
  end
17
16
  waiter
data/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Gilmour
2
- VERSION = '0.4.4'
2
+ VERSION = '0.4.5'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gilmour
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aditya Godbole
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-08-15 00:00:00.000000000 Z
12
+ date: 2015-08-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -81,20 +81,6 @@ dependencies:
81
81
  - - ">="
82
82
  - !ruby/object:Gem::Version
83
83
  version: '0'
84
- - !ruby/object:Gem::Dependency
85
- name: amqp
86
- requirement: !ruby/object:Gem::Requirement
87
- requirements:
88
- - - ">="
89
- - !ruby/object:Gem::Version
90
- version: '0'
91
- type: :runtime
92
- prerelease: false
93
- version_requirements: !ruby/object:Gem::Requirement
94
- requirements:
95
- - - ">="
96
- - !ruby/object:Gem::Version
97
- version: '0'
98
84
  description: This gem provides a Sinatra like DSL and a simple protocol to enable
99
85
  writing services that communicate over AMQP
100
86
  email: