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 +4 -4
- data/lib/combi/buses/http.rb +6 -5
- data/lib/combi/buses/in_process.rb +10 -7
- data/lib/combi/buses/queue.rb +7 -2
- data/lib/combi/buses/web_socket.rb +9 -3
- data/lib/combi/helpers.rb +10 -4
- data/lib/combi/queue_service.rb +1 -3
- data/lib/combi/response_store.rb +7 -2
- data/lib/combi/version.rb +1 -1
- data/spec/integration/multi_bus_spec.rb +7 -9
- data/spec/shared_examples/standard_bus.rb +10 -11
- data/spec/support/rabbitmq_server.rb +6 -2
- data/spec/support/web_server.rb +8 -2
- data/spec/support/websocket_server.rb +0 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f8dd32e52dae0a89b7735c068747bea3631b916
|
4
|
+
data.tar.gz: 1358f37dd615511fa8167aec2eb1216a01b40090
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 006f1a70c15f329a70d8c66ff5778bc56f476cfb487456aec27c9cf010941f9008ad078353e437645cbed41300dce201cb1e40077243d769a0b293c9e1f8f5d3
|
7
|
+
data.tar.gz: 785e8e846ac024b3a56b0551113f3a190e017ede7ce78237b718a74a22e9b43c489609baf8b6e65dd05ef14a489b79ce95061d6fdaf6d30e0d439b87b77c740c
|
data/lib/combi/buses/http.rb
CHANGED
@@ -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:
|
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:
|
64
|
+
{result: 'error', response: {error: 'unknown action'}}
|
65
65
|
end
|
66
66
|
else
|
67
|
-
{result: 'error', response: {error:
|
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
|
-
|
87
|
+
parsed = JSON.parse(r.response)
|
88
|
+
waiter.succeed(parsed['response'])
|
88
89
|
end
|
89
90
|
request_async.errback do |x|
|
90
|
-
waiter.fail(
|
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' =>
|
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
|
-
|
30
|
-
waiter.fail RuntimeError.new(Timeout::Error)
|
35
|
+
waiter.fail Timeout::Error.new
|
31
36
|
rescue Exception => e
|
32
|
-
|
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' =>
|
40
|
+
waiter.fail('error' => 'unknown action')
|
38
41
|
end
|
39
42
|
end
|
40
43
|
waiter
|
data/lib/combi/buses/queue.rb
CHANGED
@@ -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:
|
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:
|
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:
|
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:
|
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:
|
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
|
-
|
13
|
+
success_response = response
|
10
14
|
waiter_thread.wakeup
|
11
15
|
}
|
12
16
|
defer.errback { |response|
|
13
|
-
|
14
|
-
|
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
|
|
data/lib/combi/queue_service.rb
CHANGED
data/lib/combi/response_store.rb
CHANGED
@@ -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
|
-
|
19
|
-
|
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
@@ -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.
|
34
|
+
defer.fail('other service failed')
|
35
35
|
else
|
36
|
-
defer.
|
36
|
+
defer.fail('unknown error')
|
37
37
|
end
|
38
38
|
else
|
39
|
-
if service_result.respond_to?(:keys) && service_result['error']
|
40
|
-
defer.
|
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);
|
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
|
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
|
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 '
|
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
|
-
|
71
|
-
|
72
|
-
|
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
|
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
|
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
|
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
|
-
|
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
|
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
|
data/spec/support/web_server.rb
CHANGED
@@ -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.
|
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-
|
12
|
+
date: 2014-06-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: yajl-ruby
|