combi 0.0.9 → 0.0.10

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
1
  ---
2
2
  SHA1:
3
- metadata.gz: 842db51c04bfe53f9a03dee7e7a7dcd1c82d7256
4
- data.tar.gz: a18fba47f8b819d81f994a2afbe7d2243a459b6b
3
+ metadata.gz: 3f8dd32e52dae0a89b7735c068747bea3631b916
4
+ data.tar.gz: 1358f37dd615511fa8167aec2eb1216a01b40090
5
5
  SHA512:
6
- metadata.gz: 50e91d8a37b80e45563311c0b0e6c5d7ced744388292b9a4e964138f45d392c337b19d3cc128bfc713ad8dd5fe7e13846bace1d7a707257dbac1e2177483c5f5
7
- data.tar.gz: 8448f3cb3c208674c7f7ebe225b0827d3914a5378064dad0633ac6c6bca6797424039276a4c4839a99921b3aaca0b0c0ca736f972c85c6a604785e052b81c6e3
6
+ metadata.gz: 006f1a70c15f329a70d8c66ff5778bc56f476cfb487456aec27c9cf010941f9008ad078353e437645cbed41300dce201cb1e40077243d769a0b293c9e1f8f5d3
7
+ data.tar.gz: 785e8e846ac024b3a56b0551113f3a190e017ede7ce78237b718a74a22e9b43c489609baf8b6e65dd05ef14a489b79ce95061d6fdaf6d30e0d439b87b77c740c
@@ -57,14 +57,14 @@ module Combi
57
57
  begin
58
58
  response = service_instance.send(kind, message['payload'])
59
59
  rescue Exception => e
60
- response = {error: true, message: e.message}
60
+ response = {error: {message: e.message, backtrace: e.backtrace } }
61
61
  end
62
62
  {result: 'ok', response: response}
63
63
  else
64
- {result: 'error', response: {error: true, message: 'unknown action'}}
64
+ {result: 'error', response: {error: 'unknown action'}}
65
65
  end
66
66
  else
67
- {result: 'error', response: {error: true, message: 'unknown service'}}
67
+ {result: 'error', response: {error: 'unknown service'}}
68
68
  end
69
69
  end
70
70
 
@@ -84,10 +84,11 @@ module Combi
84
84
  url = "#{@options[:remote_api]}#{name}/#{kind}"
85
85
  request_async = EventMachine::HttpRequest.new(url, connection_timeout: options[:timeout]).post(body: message.to_json)
86
86
  request_async.callback do |r|
87
- waiter.succeed(JSON.parse(r.response)['response'])
87
+ parsed = JSON.parse(r.response)
88
+ waiter.succeed(parsed['response'])
88
89
  end
89
90
  request_async.errback do |x|
90
- waiter.fail(RuntimeError.new(Timeout::Error))
91
+ waiter.fail(Timeout::Error.new)
91
92
  end
92
93
  waiter
93
94
  end
@@ -8,7 +8,7 @@ module Combi
8
8
  handler = memory_handlers[handler_name.to_s]
9
9
  waiter = EventMachine::DefaultDeferrable.new
10
10
  if handler.nil?
11
- waiter.fail('error' => true, 'message' => 'unknown service')
11
+ waiter.fail('error' => 'unknown service')
12
12
  else
13
13
  service_instance = handler[:service_instance]
14
14
  message = JSON.parse(message.to_json)
@@ -19,22 +19,25 @@ module Combi
19
19
  response = service_instance.send(kind, message)
20
20
  if response.respond_to? :succeed
21
21
  response.callback do |service_response|
22
+ log "responding with deferred response: #{service_response.inspect[0..500]}"
22
23
  waiter.succeed service_response
23
24
  end
25
+ response.errback do |service_response|
26
+ failure_response = { 'error' => service_response }
27
+ log "responding with deferred failure: #{service_response.inspect[0..500]}"
28
+ waiter.fail(failure_response)
29
+ end
24
30
  else
25
31
  waiter.succeed response
26
32
  end
27
33
  end
28
34
  rescue Timeout::Error => e
29
- log "ERROR"
30
- waiter.fail RuntimeError.new(Timeout::Error)
35
+ waiter.fail Timeout::Error.new
31
36
  rescue Exception => e
32
- log "other ERROR"
33
- log e.inspect
34
- waiter.fail({'error' => true, 'message' => e.message})
37
+ waiter.fail 'error' => { 'message' => e.message, 'backtrace' => e.backtrace}
35
38
  end
36
39
  else
37
- waiter.fail('error' => true, 'message' => 'unknown action')
40
+ waiter.fail('error' => 'unknown action')
38
41
  end
39
42
  end
40
43
  waiter
@@ -69,11 +69,11 @@ module Combi
69
69
  begin
70
70
  response = service_instance.send(kind, payload)
71
71
  rescue Exception => e
72
- response = {error: true, message: e.message}
72
+ response = {error: { message: e.message, backtrace: e.backtrace } }
73
73
  end
74
74
  else
75
75
  log "Service instance does not respond to #{kind}: #{service_instance.inspect}"
76
- response = {error: true, message: 'unknown action'}
76
+ response = {error: 'unknown action'}
77
77
  end
78
78
  if response.respond_to? :succeed
79
79
  log "response is deferred"
@@ -81,6 +81,11 @@ module Combi
81
81
  log "responding with deferred answer: #{service_response.inspect[0..500]}"
82
82
  queue_service.respond(service_response.to_json, delivery_info)
83
83
  end
84
+ response.errback do |service_response|
85
+ failure_response = { error: service_response }
86
+ log "responding with deferred failure: #{service_response.inspect[0..500]}"
87
+ queue_service.respond(failure_response.to_json, delivery_info)
88
+ end
84
89
  else
85
90
  log "responding with inmediate answer: #{response.inspect[0..500]}"
86
91
  queue_service.respond(response.to_json, delivery_info)
@@ -173,7 +173,7 @@ module Combi
173
173
  begin
174
174
  response = invoke_service(service_name, kind, payload)
175
175
  rescue Exception => e
176
- response = {error: true, message: e.message}
176
+ response = {error: {message: e.message, backtrace: e.backtrace } }
177
177
  end
178
178
 
179
179
  msg = {result: 'ok', correlation_id: message['correlation_id']}
@@ -185,6 +185,12 @@ module Combi
185
185
  msg[:response] = service_response.to_json
186
186
  ws.send(msg.to_json)
187
187
  end
188
+ response.errback do |service_response|
189
+ log "responding with deferred error: #{service_response.inspect[0..500]}"
190
+ error_response = { error: service_response }
191
+ msg[:response] = error_response.to_json
192
+ ws.send(msg.to_json)
193
+ end
188
194
  else
189
195
  log "responding with inmediate answer: #{response.inspect[0..500]}"
190
196
  msg[:response] = response.to_json
@@ -200,12 +206,12 @@ module Combi
200
206
  response = service_instance.send(kind, payload)
201
207
  else
202
208
  log "[WARNING] Service #{service_name}(#{service_instance.class.name}) does not respond to message #{kind}"
203
- response = {error: true, message: 'unknown action'}
209
+ response = {error: 'unknown action'}
204
210
  end
205
211
  else
206
212
  log "[WARNING] Service #{service_name} not found"
207
213
  log "[WARNING] handlers: #{handlers.keys.inspect}"
208
- response = {error: true, message: 'unknown service'}
214
+ response = {error: 'unknown service'}
209
215
  end
210
216
  end
211
217
 
data/lib/combi/helpers.rb CHANGED
@@ -2,21 +2,27 @@ require 'timeout'
2
2
 
3
3
  module Combi
4
4
 
5
+ class ServiceError < StandardError
6
+ end
7
+
5
8
  def self.wait_for(defer, options = {}, &block)
6
9
  options[:timeout] ||= 2
7
10
  waiter_thread = Thread.current
11
+ success_response, error_response = nil
8
12
  defer.callback { |response|
9
- block.call response
13
+ success_response = response
10
14
  waiter_thread.wakeup
11
15
  }
12
16
  defer.errback { |response|
13
- log "waiting for result, received an error"
14
- log response
15
- block.call error: true, message: 'service request error'
17
+ STDERR << "waiting for result, received an error: #{response.inspect}\n"
18
+ error_response = response
16
19
  waiter_thread.wakeup
17
20
  }
18
21
  Timeout::timeout(options[:timeout]) do
19
22
  Thread.stop
23
+ puts "\t AFTER STOP"
24
+ raise ServiceError.new(error_response) if error_response
25
+ block.call success_response
20
26
  end
21
27
  end
22
28
 
@@ -43,9 +43,7 @@ module Combi
43
43
  end
44
44
 
45
45
  def disconnect
46
- @amqp_conn.close do
47
- puts "disconnected from RABBIT"
48
- end
46
+ @amqp_conn.close
49
47
  end
50
48
 
51
49
  def publish(*args, &block)
@@ -15,8 +15,13 @@ module Combi
15
15
  def handle_rpc_response(response)
16
16
  correlation_id = response['correlation_id']
17
17
  waiter = @waiters[correlation_id]
18
- response = response['response']
19
- waiter.succeed(JSON.parse response) if waiter.respond_to? :succeed
18
+ return unless waiter
19
+ response = JSON.parse response['response']
20
+ if response.respond_to?(:keys) and response['error']
21
+ waiter.fail(response)
22
+ else
23
+ waiter.succeed(response)
24
+ end
20
25
  end
21
26
 
22
27
  def finish(key)
data/lib/combi/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Combi
2
- VERSION = '0.0.9'
2
+ VERSION = '0.0.10'
3
3
  end
@@ -31,13 +31,13 @@ describe "in a multi bus environment" do
31
31
  service_result = EM::Synchrony.sync req
32
32
  if service_result.is_a? RuntimeError
33
33
  if @other_client.is_a?(Combi::Queue) && service_result.message == "Timeout::Error"
34
- defer.succeed({'error' => true, 'message' => 'other service failed'})
34
+ defer.fail('other service failed')
35
35
  else
36
- defer.succeed({'error' => true, 'message' => 'unknown error'})
36
+ defer.fail('unknown error')
37
37
  end
38
38
  else
39
- if service_result.respond_to?(:keys) && service_result['error'] == true
40
- defer.succeed({'error' => true, 'message' => 'other service failed'})
39
+ if service_result.respond_to?(:keys) && service_result['error']
40
+ defer.fail('other service failed')
41
41
  else
42
42
  defer.succeed(service_result*2)
43
43
  end
@@ -51,7 +51,7 @@ describe "in a multi bus environment" do
51
51
  Given(:broken_service) do
52
52
  Module.new do
53
53
  def actions; [:say_hello_if_you_can]; end
54
- def do_it(params); puts "raising error"; raise "I can't talk" ; end
54
+ def do_it(params); raise "I can't talk" ; end
55
55
  end
56
56
  end
57
57
 
@@ -173,8 +173,7 @@ describe "in a multi bus environment" do
173
173
  prepare
174
174
  EM.synchrony do
175
175
  service_result = EM::Synchrony.sync main_bus_consumer.request(:say_hello_if_you_can, :do_it, params, options)
176
- service_result['error'].should be_true
177
- service_result['message'].should eq "I can't talk"
176
+ service_result['error']['message'].should eq "I can't talk"
178
177
  done
179
178
  finalize
180
179
  end
@@ -192,8 +191,7 @@ describe "in a multi bus environment" do
192
191
  EM.synchrony do
193
192
  params.merge!('service_name' => 'say_hello_if_you_can')
194
193
  service_result = EM::Synchrony.sync main_bus_consumer.request(:repeat_with_me, :do_it, params, options)
195
- service_result['error'].should be_true
196
- service_result['message'].should eq 'other service failed'
194
+ service_result['error'].should eq 'other service failed'
197
195
  done
198
196
  finalize
199
197
  end
@@ -59,7 +59,7 @@ shared_examples_for "standard_bus" do
59
59
  end
60
60
  end
61
61
 
62
- context 'raises Timeout::Error when the response is slow' do
62
+ context 'fails with error => Timeout::Error when the response is slow' do
63
63
  Given(:time_base) { 0.01 }
64
64
  When(:params) { { time: time_base*4 } }
65
65
  When(:service) { provider.add_service slow_service }
@@ -67,10 +67,9 @@ shared_examples_for "standard_bus" do
67
67
  em do
68
68
  prepare
69
69
  EM.synchrony do
70
- expect do
71
- service_result = EM::Synchrony.sync consumer.request(:sleep, :do_it, params, { timeout: time_base/2.0 })
72
- raise Kernel.const_get(service_result.message) if service_result.is_a? Exception
73
- end.to raise_error Timeout::Error
70
+ service_result = EM::Synchrony.sync consumer.request(:sleep, :do_it, params, { timeout: time_base/2.0 })
71
+ service_result.should be_an Exception
72
+ service_result.message.should eq 'Timeout::Error'
74
73
  done(time_base) #timeout response must came before this timeout
75
74
  end
76
75
  finalize
@@ -143,8 +142,10 @@ shared_examples_for "standard_bus" do
143
142
  prepare
144
143
  EM.synchrony do
145
144
  service_result = EM::Synchrony.sync consumer.request(:shout_error, :do_it, {message: error_message}, { timeout: 0.1 })
146
- service_result['error'].should be_true
147
- service_result['message'].should eq error_message
145
+ service_result['error'].should be_a Hash
146
+ service_result['error']['message'].should eq error_message
147
+ service_result['error']['backtrace'].should_not be_nil
148
+ service_result['error']['backtrace'].should be_an Array
148
149
  done
149
150
  finalize
150
151
  end
@@ -165,8 +166,7 @@ shared_examples_for "standard_bus" do
165
166
  consumer.class.should eq Combi::Queue
166
167
  service_result.message.should eq "Timeout::Error"
167
168
  else
168
- service_result['error'].should be_true
169
- service_result['message'].should eq error_message
169
+ service_result['error'].should eq error_message
170
170
  end
171
171
  done
172
172
  finalize
@@ -185,8 +185,7 @@ shared_examples_for "standard_bus" do
185
185
  EM.synchrony do
186
186
  begin
187
187
  service_result = EM::Synchrony.sync consumer.request(:echo_this, :do_other, {}, { timeout: 0.1 })
188
- service_result['error'].should be_true
189
- service_result['message'].should eq error_message
188
+ service_result['error'].should eq error_message
190
189
  done
191
190
  finalize
192
191
  end
@@ -27,7 +27,9 @@ class RabbitmqServer
27
27
  end
28
28
 
29
29
  def start_forwarder!
30
- @forwarder_pid = Process.spawn '/usr/local/bin/boot2docker', 'ssh', '-L', "#{port}:localhost:#{port}", '-N'
30
+ command = "/usr/local/bin/boot2docker ssh -L #{port}:localhost:#{port} -N"
31
+ return if @_command_running ||= `ps`.include?(command)
32
+ @forwarder_pid = Process.spawn command
31
33
  #Process.detach @forwarder_pid
32
34
  puts "starting forwarder pid: #{@forwarder_pid}"
33
35
  end
@@ -53,14 +55,16 @@ class RabbitmqServer
53
55
 
54
56
  def is_port_open?(ip, port, timeout = 15)
55
57
  begin
58
+ service = "rabbit @ #{ip}##{port}"
56
59
  Timeout::timeout(timeout) do
57
60
  begin
58
61
  s = TCPSocket.new(ip, port)
59
62
  s.close
60
63
  return true
61
64
  rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
62
- puts "conn error to rabbit @ #{ip}##{port}"
65
+ puts "conn error to #{service}"
63
66
  sleep 1
67
+ puts "\tretrying connection to #{service}"
64
68
  retry
65
69
  end
66
70
  end
@@ -13,6 +13,13 @@ class DeferrableBody
13
13
  self.succeed
14
14
  end
15
15
  end
16
+ @defer.errback do |service_response|
17
+ error_response = { error: service_response }
18
+ EM::next_tick do
19
+ self.call [{result: 'ok', response: error_response}.to_json]
20
+ self.fail
21
+ end
22
+ end
16
23
  end
17
24
 
18
25
  def each(&block)
@@ -29,7 +36,6 @@ end
29
36
 
30
37
  def start_web_server(http_bus, port, webserver = 'thin')
31
38
  require webserver
32
- puts "starting web server '#{webserver}' at port #{port}"
33
39
  app = lambda do |env|
34
40
  response_message = http_bus.manage_request(env)
35
41
  if response_message[:response].respond_to? :succeed
@@ -43,8 +49,8 @@ def start_web_server(http_bus, port, webserver = 'thin')
43
49
  response_rack
44
50
  end
45
51
  end
52
+ Thin::Logging.silent = true if webserver == 'thin'
46
53
  rack_handler = Rack::Handler.get(webserver)
47
54
  rack_handler.run app, Port: port
48
- puts "EM WEB STARTED"
49
55
  sleep 0.1
50
56
  end
@@ -1,13 +1,11 @@
1
1
  require 'em-websocket'
2
2
 
3
3
  def start_em_websocket_server(websocket_bus, port)
4
- puts "starting websocket server at port #{port}"
5
4
  ws_handler = Class.new do
6
5
  def new_session(arg); end
7
6
  end.new
8
7
  EM::WebSocket.start(host: '0.0.0.0', port: port) do |ws|
9
8
  websocket_bus.manage_ws_event(ws, ws_handler)
10
9
  end
11
- puts "EM WEBSOCKET STARTED"
12
10
  sleep 0.1
13
11
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: combi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - German Del Zotto
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-05-30 00:00:00.000000000 Z
12
+ date: 2014-06-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: yajl-ruby