rjr 0.11.7 → 0.12.2
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.
- data/bin/rjr-client +1 -1
- data/bin/rjr-client-launcher +5 -6
- data/lib/rjr/amqp_node.rb +4 -2
- data/lib/rjr/inspect.rb +1 -2
- data/lib/rjr/local_node.rb +66 -30
- data/lib/rjr/message.rb +1 -1
- data/lib/rjr/tcp_node.rb +5 -3
- data/lib/rjr/thread_pool2.rb +1 -0
- data/lib/rjr/util.rb +1 -1
- data/lib/rjr/web_node.rb +3 -2
- data/lib/rjr/ws_node.rb +4 -2
- metadata +2 -2
data/bin/rjr-client
CHANGED
@@ -67,7 +67,7 @@ optparse = OptionParser.new do |opts|
|
|
67
67
|
end
|
68
68
|
|
69
69
|
opts.on('--message ID', 'Message to send to server (rand to select random)') do |mid|
|
70
|
-
config[:msg_id] = mid
|
70
|
+
config[:msg_id] = mid.intern
|
71
71
|
end
|
72
72
|
|
73
73
|
opts.on('--interval seconds', 'Number of seconds after which to wait between requests (or rand)') do |s|
|
data/bin/rjr-client-launcher
CHANGED
@@ -8,12 +8,12 @@ ID_OFFSET = ARGV.shift.to_i || 100
|
|
8
8
|
|
9
9
|
NUM_CLIENTS = 5
|
10
10
|
NUM_MSGS = 20 # per client
|
11
|
+
MSG_ID = :rand
|
11
12
|
NODE_ID = 'rjr_test_launcher-'
|
12
|
-
|
13
|
-
|
14
|
-
#:tcp => 'jsonrpc://localhost:8181',
|
13
|
+
TRANSPORTS = {:amqp => 'rjr_test_server-queue',
|
14
|
+
:tcp => 'jsonrpc://localhost:8181',
|
15
15
|
:ws => 'jsonrpc://localhost:8080',
|
16
|
-
|
16
|
+
:www => 'http://localhost:8888'
|
17
17
|
}
|
18
18
|
BROKER = 'localhost' # only used for amqp
|
19
19
|
MSG_INTERVAL= 3
|
@@ -27,11 +27,10 @@ threads = []
|
|
27
27
|
dst = TRANSPORTS[transport]
|
28
28
|
mode = rand(2) == 0 ? :msg : :rand
|
29
29
|
node_id = NODE_ID + (i + ID_OFFSET).to_s
|
30
|
-
msg_id = MSG_IDS[rand(MSG_IDS.size)]
|
31
30
|
|
32
31
|
threads <<
|
33
32
|
Thread.new{
|
34
|
-
system("#{CLIENT} -m #{mode} -t #{transport} -i #{node_id} -b #{BROKER} --dst #{dst} -n #{NUM_MSGS} --message #{
|
33
|
+
system(ENV, "#{CLIENT} -m #{mode} -t #{transport} -i #{node_id} -b #{BROKER} --dst #{dst} -n #{NUM_MSGS} --message #{MSG_ID} --interval #{MSG_INTERVAL}")
|
35
34
|
}
|
36
35
|
}
|
37
36
|
|
data/lib/rjr/amqp_node.rb
CHANGED
@@ -21,6 +21,7 @@ else
|
|
21
21
|
require 'rjr/node'
|
22
22
|
require 'rjr/message'
|
23
23
|
require 'rjr/dispatcher'
|
24
|
+
require 'rjr/errors'
|
24
25
|
require 'rjr/thread_pool2'
|
25
26
|
|
26
27
|
module RJR
|
@@ -309,17 +310,18 @@ class AMQPNode < RJR::Node
|
|
309
310
|
published_l = Mutex.new
|
310
311
|
published_c = ConditionVariable.new
|
311
312
|
|
313
|
+
invoked = false
|
312
314
|
message = NotificationMessage.new :method => rpc_method,
|
313
315
|
:args => args,
|
314
316
|
:headers => @message_headers
|
315
317
|
em_run do
|
316
318
|
init_node {
|
317
319
|
publish(message.to_s, :routing_key => routing_key, :reply_to => @queue_name){
|
318
|
-
published_l.synchronize { published_c.signal }
|
320
|
+
published_l.synchronize { invoked = true ; published_c.signal }
|
319
321
|
}
|
320
322
|
}
|
321
323
|
end
|
322
|
-
published_l.synchronize { published_c.wait published_l }
|
324
|
+
published_l.synchronize { published_c.wait published_l unless invoked }
|
323
325
|
nil
|
324
326
|
end
|
325
327
|
|
data/lib/rjr/inspect.rb
CHANGED
@@ -52,9 +52,8 @@ rjr_method \
|
|
52
52
|
{
|
53
53
|
# event machine
|
54
54
|
:event_machine => { :running => EMAdapter.running?,
|
55
|
-
:has_jobs => EMAdapter.has_jobs?,
|
56
55
|
:thread_status => EMAdapter.reactor_thread.status,
|
57
|
-
:
|
56
|
+
:connections => EventMachine.connection_count },
|
58
57
|
|
59
58
|
# thread pool
|
60
59
|
:thread_pool => { :running => ThreadPool2Manager.thread_pool.running?,
|
data/lib/rjr/local_node.rb
CHANGED
@@ -8,6 +8,7 @@
|
|
8
8
|
require 'rjr/node'
|
9
9
|
require 'rjr/message'
|
10
10
|
require 'rjr/dispatcher'
|
11
|
+
require 'rjr/errors'
|
11
12
|
|
12
13
|
module RJR
|
13
14
|
|
@@ -23,8 +24,11 @@ class LocalNodeCallback
|
|
23
24
|
# Implementation of {RJR::NodeCallback#invoke}
|
24
25
|
def invoke(callback_method, *data)
|
25
26
|
# TODO any exceptions from handler will propagate here, surround w/ begin/rescue block
|
26
|
-
|
27
|
-
|
27
|
+
# TODO support local_node 'disconnections' via RJR::ConnectionError & triggering mechanism
|
28
|
+
ThreadPool2Manager <<
|
29
|
+
ThreadPool2Job.new(callback_method, data) { |m|
|
30
|
+
@node.local_dispatch(callback_method, *data)
|
31
|
+
}
|
28
32
|
end
|
29
33
|
end
|
30
34
|
|
@@ -50,6 +54,43 @@ class LocalNode < RJR::Node
|
|
50
54
|
# allows clients to override the node type for the local node
|
51
55
|
attr_accessor :node_type
|
52
56
|
|
57
|
+
# Helper method to locally dispatch method/args
|
58
|
+
#
|
59
|
+
# TODO would like to make private but needed in LocalNodeCallback
|
60
|
+
def local_dispatch(rpc_method, *args)
|
61
|
+
# create request from args
|
62
|
+
0.upto(args.size).each { |i| args[i] = args[i].to_s if args[i].is_a?(Symbol) }
|
63
|
+
message = RequestMessage.new :method => rpc_method,
|
64
|
+
:args => args,
|
65
|
+
:headers => @message_headers
|
66
|
+
|
67
|
+
# here we serialize / unserialze messages to/from json to
|
68
|
+
# ensure local node complies to same json-rpc restrictions as other nodes
|
69
|
+
message = RequestMessage.new :message => message.to_s,
|
70
|
+
:headers => @message_headers
|
71
|
+
|
72
|
+
result = Dispatcher.dispatch_request(message.jr_method,
|
73
|
+
:method_args => message.jr_args,
|
74
|
+
:headers => @message_headers,
|
75
|
+
:rjr_node => self,
|
76
|
+
:rjr_node_id => @node_id,
|
77
|
+
:rjr_node_type => @node_type,
|
78
|
+
:rjr_callback =>
|
79
|
+
LocalNodeCallback.new(:node => self,
|
80
|
+
:headers => @message_headers))
|
81
|
+
|
82
|
+
# create response message from result
|
83
|
+
response = ResponseMessage.new(:id => message.msg_id,
|
84
|
+
:result => result,
|
85
|
+
:headers => @message_headers)
|
86
|
+
|
87
|
+
# same comment on serialization/unserialization as above
|
88
|
+
response = ResponseMessage.new(:message => response.to_s,
|
89
|
+
:headers => @message_headers)
|
90
|
+
|
91
|
+
response
|
92
|
+
end
|
93
|
+
|
53
94
|
# LocalNode initializer
|
54
95
|
# @param [Hash] args the options to create the local node with
|
55
96
|
def initialize(args = {})
|
@@ -71,44 +112,39 @@ class LocalNode < RJR::Node
|
|
71
112
|
#
|
72
113
|
# Currently does nothing as method handlers can be invoked directly upon invoke_request
|
73
114
|
def listen
|
74
|
-
em_run do
|
75
|
-
end
|
76
115
|
end
|
77
116
|
|
78
117
|
# Instructs node to send rpc request, and wait for and return response
|
118
|
+
#
|
119
|
+
# If strictly confirming to other nodes, use event machine to launch
|
120
|
+
# a thread pool job to dispatch request and block on result.
|
121
|
+
# Optimized for performance reasons but recognize the semantics of using
|
122
|
+
# the local node will be somewhat different.
|
123
|
+
#
|
79
124
|
# @param [String] rpc_method json-rpc method to invoke on destination
|
80
125
|
# @param [Array] args array of arguments to convert to json and invoke remote method wtih
|
81
126
|
# @return [Object] the json result retrieved from destination converted to a ruby object
|
82
127
|
# @raise [Exception] if the destination raises an exception, it will be converted to json and re-raised here
|
83
128
|
def invoke_request(rpc_method, *args)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
:headers => @message_headers
|
88
|
-
|
89
|
-
# we serialize / unserialze messages to ensure local node complies
|
90
|
-
# to same json-rpc restrictions as other nodes
|
91
|
-
message = RequestMessage.new :message => message.to_s,
|
92
|
-
:headers => @message_headers
|
93
|
-
|
94
|
-
result = Dispatcher.dispatch_request(message.jr_method,
|
95
|
-
:method_args => message.jr_args,
|
96
|
-
:headers => @message_headers,
|
97
|
-
:rjr_node => self,
|
98
|
-
:rjr_node_id => @node_id,
|
99
|
-
:rjr_node_type => @node_type,
|
100
|
-
:rjr_callback =>
|
101
|
-
LocalNodeCallback.new(:node => self,
|
102
|
-
:headers => @message_headers))
|
103
|
-
response = ResponseMessage.new(:id => message.msg_id,
|
104
|
-
:result => result,
|
105
|
-
:headers => @message_headers)
|
129
|
+
res = local_dispatch(rpc_method, *args)
|
130
|
+
return Dispatcher.handle_response(res.result)
|
131
|
+
end
|
106
132
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
133
|
+
# Instructs node to send rpc notification (immediately returns / no response is generated)
|
134
|
+
#
|
135
|
+
# Same performance comment as invoke_request above
|
136
|
+
#
|
137
|
+
# @param [String] rpc_method json-rpc method to invoke on destination
|
138
|
+
# @param [Array] args array of arguments to convert to json and invoke remote method wtih
|
139
|
+
def send_notification(rpc_method, *args)
|
140
|
+
# TODO run in thread & immediately return?
|
141
|
+
begin
|
142
|
+
local_dispatch(rpc_method, *args)
|
143
|
+
rescue
|
144
|
+
end
|
145
|
+
nil
|
111
146
|
end
|
112
147
|
|
148
|
+
|
113
149
|
end
|
114
150
|
end
|
data/lib/rjr/message.rb
CHANGED
data/lib/rjr/tcp_node.rb
CHANGED
@@ -13,6 +13,7 @@ require 'rjr/node'
|
|
13
13
|
require 'rjr/message'
|
14
14
|
require 'rjr/message'
|
15
15
|
require 'rjr/dispatcher'
|
16
|
+
require 'rjr/errors'
|
16
17
|
require 'rjr/thread_pool2'
|
17
18
|
|
18
19
|
module RJR
|
@@ -37,7 +38,7 @@ class TCPNodeCallback
|
|
37
38
|
# Implementation of {RJR::NodeCallback#invoke}
|
38
39
|
def invoke(callback_method, *data)
|
39
40
|
msg = NotificationMessage.new :method => callback_method, :args => data, :headers => @message_headers
|
40
|
-
# TODO surround w/ begin/rescue block incase of socket errors
|
41
|
+
# TODO surround w/ begin/rescue block incase of socket errors / raise RJR::ConnectionError
|
41
42
|
@endpoint.safe_send msg.to_s
|
42
43
|
end
|
43
44
|
end
|
@@ -298,6 +299,7 @@ class TCPNode < RJR::Node
|
|
298
299
|
uri = URI.parse(uri)
|
299
300
|
host,port = uri.host, uri.port
|
300
301
|
|
302
|
+
invoked = false
|
301
303
|
conn = nil
|
302
304
|
message = NotificationMessage.new :method => rpc_method,
|
303
305
|
:args => args,
|
@@ -309,10 +311,10 @@ class TCPNode < RJR::Node
|
|
309
311
|
c.safe_send message.to_s
|
310
312
|
# XXX big bug w/ tcp node, this should be invoked only when
|
311
313
|
# we are sure event machine sent message
|
312
|
-
published_l.synchronize { published_c.signal }
|
314
|
+
published_l.synchronize { invoked = true ; published_c.signal }
|
313
315
|
}
|
314
316
|
}
|
315
|
-
published_l.synchronize { published_c.wait published_l }
|
317
|
+
published_l.synchronize { published_c.wait published_l unless invoked }
|
316
318
|
#sleep 0.01 until conn.get_outbound_data_size == 0
|
317
319
|
nil
|
318
320
|
end
|
data/lib/rjr/thread_pool2.rb
CHANGED
data/lib/rjr/util.rb
CHANGED
data/lib/rjr/web_node.rb
CHANGED
@@ -247,16 +247,17 @@ class WebNode < RJR::Node
|
|
247
247
|
published_l = Mutex.new
|
248
248
|
published_c = ConditionVariable.new
|
249
249
|
|
250
|
+
invoked = false
|
250
251
|
message = NotificationMessage.new :method => rpc_method,
|
251
252
|
:args => args,
|
252
253
|
:headers => @message_headers
|
253
|
-
cb = lambda { |arg| published_l.synchronize { published_c.signal }}
|
254
|
+
cb = lambda { |arg| published_l.synchronize { invoked = true ; published_c.signal }}
|
254
255
|
em_run do
|
255
256
|
http = EventMachine::HttpRequest.new(uri).post :body => message.to_s
|
256
257
|
http.errback &cb
|
257
258
|
http.callback &cb
|
258
259
|
end
|
259
|
-
published_l.synchronize { published_c.wait published_l }
|
260
|
+
published_l.synchronize { published_c.wait published_l unless invoked }
|
260
261
|
nil
|
261
262
|
end
|
262
263
|
end
|
data/lib/rjr/ws_node.rb
CHANGED
@@ -23,6 +23,7 @@ require 'socket'
|
|
23
23
|
require 'rjr/node'
|
24
24
|
require 'rjr/message'
|
25
25
|
require 'rjr/dispatcher'
|
26
|
+
require 'rjr/errors'
|
26
27
|
require 'rjr/thread_pool2'
|
27
28
|
|
28
29
|
module RJR
|
@@ -265,6 +266,7 @@ class WSNode < RJR::Node
|
|
265
266
|
published_l = Mutex.new
|
266
267
|
published_c = ConditionVariable.new
|
267
268
|
|
269
|
+
invoked = false
|
268
270
|
message = NotificationMessage.new :method => rpc_method,
|
269
271
|
:args => args,
|
270
272
|
:headers => @message_headers
|
@@ -275,10 +277,10 @@ class WSNode < RJR::Node
|
|
275
277
|
# XXX same bug w/ tcp node, due to nature of event machine
|
276
278
|
# we aren't guaranteed that message is actually written to socket
|
277
279
|
# here, process must be kept alive until data is sent or will be lost
|
278
|
-
published_l.synchronize { published_c.signal }
|
280
|
+
published_l.synchronize { invoked = true ; published_c.signal }
|
279
281
|
end
|
280
282
|
}
|
281
|
-
published_l.synchronize { published_c.wait published_l }
|
283
|
+
published_l.synchronize { published_c.wait published_l unless invoked }
|
282
284
|
nil
|
283
285
|
end
|
284
286
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rjr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-04-
|
12
|
+
date: 2013-04-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|