mqrpc 0.0.6 → 0.0.7
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/lib/mqrpc/agent.rb +65 -38
- data/lib/mqrpc/functions/ping.rb +3 -1
- data/lib/mqrpc/logger.rb +13 -0
- data/lib/mqrpc/message.rb +4 -0
- data/lib/mqrpc/message.rb.orig +132 -0
- data/lib/mqrpc/message.rb.rej +19 -0
- data/lib/mqrpc/operation.rb +30 -7
- data/lib/mqrpc/sizedhash.rb +5 -4
- data/lib/mqrpc/test.diff +32 -0
- metadata +5 -2
data/lib/mqrpc/agent.rb
CHANGED
|
@@ -78,11 +78,7 @@ module MQRPC
|
|
|
78
78
|
case state
|
|
79
79
|
when :blocked
|
|
80
80
|
MQRPC::logger.info("Queue '#{k}' is full, unsubscribing from #{source}")
|
|
81
|
-
|
|
82
|
-
mq_q = @mq.queue(source, :durable => true)
|
|
83
|
-
mq_q.bind(exchange, :key => "*")
|
|
84
|
-
mq_q.unsubscribe
|
|
85
|
-
@queues.delete(source)
|
|
81
|
+
unsubscribe(source)
|
|
86
82
|
when :ready
|
|
87
83
|
MQRPC::logger.info("Queue '#{k}' is ready, resubscribing to #{source}")
|
|
88
84
|
subscribe(source)
|
|
@@ -113,6 +109,7 @@ module MQRPC
|
|
|
113
109
|
|
|
114
110
|
def start_amqp
|
|
115
111
|
@amqpthread = Thread.new do
|
|
112
|
+
Thread.current[:name] = "AMQP"
|
|
116
113
|
# Create connection to AMQP, and in turn, the main EventMachine loop.
|
|
117
114
|
amqp_config = {:host => @config.mqhost,
|
|
118
115
|
:port => @config.mqport,
|
|
@@ -133,11 +130,9 @@ module MQRPC
|
|
|
133
130
|
subscribe(@id)
|
|
134
131
|
|
|
135
132
|
# TODO(sissel): make this a deferred thread that reads from a Queue
|
|
136
|
-
#EM.add_periodic_timer(5) { handle_new_subscriptions }
|
|
137
133
|
EM.defer { handle_subscriptions }
|
|
138
134
|
|
|
139
135
|
EM.add_periodic_timer(1) do
|
|
140
|
-
# TODO(sissel): add locking
|
|
141
136
|
@outbuffer.each_key { |dest| flushout(dest) }
|
|
142
137
|
@outbuffer.clear
|
|
143
138
|
end
|
|
@@ -147,6 +142,7 @@ module MQRPC
|
|
|
147
142
|
|
|
148
143
|
def start_receiver
|
|
149
144
|
Thread.new do
|
|
145
|
+
Thread.current[:name] = "receiver"
|
|
150
146
|
while true
|
|
151
147
|
header, message = @receive_queue.pop
|
|
152
148
|
handle_message(header, message)
|
|
@@ -155,9 +151,27 @@ module MQRPC
|
|
|
155
151
|
end # def start_receiver
|
|
156
152
|
|
|
157
153
|
def subscribe(name)
|
|
154
|
+
MQRPC::logger.info "Wanting to subscribe to queue #{name}"
|
|
158
155
|
@want_subscriptions << [:queue, name]
|
|
159
156
|
end # def subscribe
|
|
160
157
|
|
|
158
|
+
def unsubscribe(name)
|
|
159
|
+
exchange = @mq.topic(@config.mqexchange, :durable => true)
|
|
160
|
+
mq_q = @mq.queue(name, :durable => true)
|
|
161
|
+
mq_q.bind(exchange, :key => "*")
|
|
162
|
+
|
|
163
|
+
op = Operation.new
|
|
164
|
+
mq_q.unsubscribe { op.finished }
|
|
165
|
+
op.wait_until_finished
|
|
166
|
+
@queues.delete(name)
|
|
167
|
+
|
|
168
|
+
#mq_q.unsubscribe { @queues.delete(name) }
|
|
169
|
+
## wait for unsubscribe to finish; it's async
|
|
170
|
+
#while @queues.member?(name)
|
|
171
|
+
#sleep(0.1)
|
|
172
|
+
#end
|
|
173
|
+
end # def unsubscribe
|
|
174
|
+
|
|
161
175
|
def subscribe_topic(name)
|
|
162
176
|
@want_subscriptions << [:topic, name]
|
|
163
177
|
end # def subscribe_topic
|
|
@@ -177,8 +191,13 @@ module MQRPC
|
|
|
177
191
|
return
|
|
178
192
|
end
|
|
179
193
|
|
|
180
|
-
|
|
181
|
-
|
|
194
|
+
begin
|
|
195
|
+
obj = JSON::load(msg_body)
|
|
196
|
+
rescue JSON::ParserError
|
|
197
|
+
MQRPC::logger.warn("Skipping non-JSON message: #{msg_body}")
|
|
198
|
+
hdr.ack
|
|
199
|
+
return
|
|
200
|
+
end
|
|
182
201
|
if !obj.is_a?(Array)
|
|
183
202
|
obj = [obj]
|
|
184
203
|
end
|
|
@@ -222,24 +241,52 @@ module MQRPC
|
|
|
222
241
|
end # def handle_message
|
|
223
242
|
|
|
224
243
|
def run
|
|
244
|
+
Thread.current[:name] ||= "#{self.class.name}#run"
|
|
225
245
|
@amqpthread.join
|
|
226
246
|
end # run
|
|
227
247
|
|
|
228
248
|
def can_receive?(message_class)
|
|
249
|
+
if self.class.message_handlers == nil
|
|
250
|
+
self.class.message_handlers = []
|
|
251
|
+
end
|
|
252
|
+
|
|
229
253
|
return self.class.message_handlers.include?(message_class)
|
|
230
254
|
end
|
|
231
255
|
|
|
232
256
|
def handle_subscriptions
|
|
257
|
+
Thread.current[:name] = "subscriptionhandler"
|
|
233
258
|
while true do
|
|
234
|
-
|
|
235
|
-
|
|
259
|
+
queuetype, name = @want_subscriptions.pop
|
|
260
|
+
|
|
261
|
+
case queuetype
|
|
236
262
|
when :queue
|
|
237
|
-
|
|
263
|
+
if @queues.include?(name)
|
|
264
|
+
MQRPC::logger.info "Ignoring subscription request to queue "\
|
|
265
|
+
"#{name}, already subscribed."
|
|
266
|
+
next
|
|
267
|
+
end
|
|
238
268
|
MQRPC::logger.info "Subscribing to queue #{name}"
|
|
269
|
+
# Send a dummy message to queue #{name} so there's at least
|
|
270
|
+
# one message to receive, and wake up our Operation.
|
|
271
|
+
sendmsg(name, DummyMessage.new)
|
|
239
272
|
exchange = @mq.topic(@config.mqexchange, :durable => true)
|
|
240
273
|
mq_q = @mq.queue(name, :durable => true)
|
|
241
274
|
mq_q.bind(exchange, :key => "*")
|
|
242
|
-
|
|
275
|
+
op = Operation.new
|
|
276
|
+
mq_q.subscribe(:ack => true) do |hdr, msg|
|
|
277
|
+
op.finished
|
|
278
|
+
return if msg.is_a?(DummyMessage)
|
|
279
|
+
queue = hdr.routing_key
|
|
280
|
+
MQRPC::logger.info("received message on #{queue}")
|
|
281
|
+
@receive_queue << [hdr, msg]
|
|
282
|
+
MQRPC::logger.info("finished receiving message on #{queue}")
|
|
283
|
+
MQRPC::logger.info("msg: #{msg}")
|
|
284
|
+
MQRPC::logger.info("#{queue} queue size: #{@receive_queue.length}")
|
|
285
|
+
end
|
|
286
|
+
# Wait until we receive our first message (might be DummyMessage,
|
|
287
|
+
# doesn't matter) -- this confirms we are subscribed. subscribe
|
|
288
|
+
# is async...
|
|
289
|
+
op.wait_until_finished
|
|
243
290
|
@queues << name
|
|
244
291
|
when :topic
|
|
245
292
|
MQRPC::logger.info "Subscribing to topic #{name}"
|
|
@@ -249,30 +296,9 @@ module MQRPC
|
|
|
249
296
|
:auto_delete => true).bind(exchange, :key => name)
|
|
250
297
|
mq_q.subscribe { |hdr, msg| @receive_queue << [hdr, msg] }
|
|
251
298
|
@topics << name
|
|
252
|
-
end
|
|
253
|
-
end
|
|
254
|
-
end
|
|
255
|
-
|
|
256
|
-
def handle_new_subscriptions
|
|
257
|
-
todo = @want_queues - @queues
|
|
258
|
-
todo.each do |queue|
|
|
259
|
-
MQRPC::logger.info "Subscribing to queue #{queue}"
|
|
260
|
-
mq_q = @mq.queue(queue, :durable => true)
|
|
261
|
-
mq_q.subscribe(:ack => true) { |hdr, msg| @receive_queue << [hdr, msg] }
|
|
262
|
-
@queues << queue
|
|
263
|
-
end # todo.each
|
|
264
|
-
|
|
265
|
-
todo = @want_topics - @topics
|
|
266
|
-
todo.each do |topic|
|
|
267
|
-
MQRPC::logger.info "Subscribing to topic #{topic}"
|
|
268
|
-
exchange = @mq.topic(@config.mqexchange)
|
|
269
|
-
mq_q = @mq.queue("#{@id}-#{topic}",
|
|
270
|
-
:exclusive => true,
|
|
271
|
-
:auto_delete => true).bind(exchange, :key => topic)
|
|
272
|
-
mq_q.subscribe { |hdr, msg| @receive_queue << [hdr, msg] }
|
|
273
|
-
@topics << topic
|
|
274
|
-
end # todo.each
|
|
275
|
-
end # handle_new_subscriptions
|
|
299
|
+
end # case queuetype
|
|
300
|
+
end # while true
|
|
301
|
+
end # def handle_subscriptions
|
|
276
302
|
|
|
277
303
|
def flushout(destination)
|
|
278
304
|
msgs = @outbuffer[destination]
|
|
@@ -315,7 +341,8 @@ module MQRPC
|
|
|
315
341
|
end
|
|
316
342
|
|
|
317
343
|
if block_given?
|
|
318
|
-
op = Operation.new
|
|
344
|
+
op = Operation.new &callback
|
|
345
|
+
MQRPC::logger.debug "New operation for #{msg.id}"
|
|
319
346
|
@message_operations[msg.id] = op
|
|
320
347
|
return op
|
|
321
348
|
end
|
data/lib/mqrpc/functions/ping.rb
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
require 'rubygems'
|
|
2
2
|
require 'mqrpc/messages/ping'
|
|
3
3
|
|
|
4
|
-
module MQRPC; module Functions;
|
|
4
|
+
module MQRPC; module Functions; class Ping
|
|
5
|
+
#handle MQRPC::Messages::PingRequest, :PingRequestHandler
|
|
6
|
+
|
|
5
7
|
def PingRequestHandler(request)
|
|
6
8
|
MQRPC::logger.debug "received PingRequest (#{request.pingdata})"
|
|
7
9
|
response = MQRPC::Messages::PingResponse.new
|
data/lib/mqrpc/logger.rb
CHANGED
|
@@ -13,3 +13,16 @@ module MQRPC
|
|
|
13
13
|
@logger = logger
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
|
+
|
|
17
|
+
# Make logger include the thread id.
|
|
18
|
+
class FormatterWithThread < Logger::Formatter
|
|
19
|
+
Format = "%s, [%s#%d/%s] %5s -- %s: %s\n"
|
|
20
|
+
|
|
21
|
+
def call(severity, time, progname, msg)
|
|
22
|
+
thread_id = (Thread.current[:name] or Thread.current)
|
|
23
|
+
Format % [severity[0..0], format_datetime(time), $$, thread_id,
|
|
24
|
+
severity, progname, msg2str(msg)]
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
MQRPC::logger.formatter = FormatterWithThread.new
|
data/lib/mqrpc/message.rb
CHANGED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'thread'
|
|
3
|
+
require 'mqrpc/logger'
|
|
4
|
+
|
|
5
|
+
module BindToHash
|
|
6
|
+
def header(method, key=nil)
|
|
7
|
+
key = method.to_s if key == nil
|
|
8
|
+
hashbind(method, "/#{key}")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def argument(method, key=nil)
|
|
12
|
+
key = method.to_s if key == nil
|
|
13
|
+
hashbind(method, "/args/#{key}")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
def hashbind(method, key)
|
|
18
|
+
hashpath = __genhashpath(key)
|
|
19
|
+
self.class_eval %(
|
|
20
|
+
def #{method}
|
|
21
|
+
return #{hashpath}
|
|
22
|
+
end
|
|
23
|
+
def #{method}=(val)
|
|
24
|
+
#{hashpath} = val
|
|
25
|
+
end
|
|
26
|
+
)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
def __genhashpath(key)
|
|
31
|
+
# TODO(sissel): enforce 'key' needs to be a string or symbol?
|
|
32
|
+
path = key.split("/").select { |x| x.length > 0 }\
|
|
33
|
+
.map { |x| "[#{x.inspect}]" }
|
|
34
|
+
return "@data#{path.join("")}"
|
|
35
|
+
end
|
|
36
|
+
end # modules BindToHash
|
|
37
|
+
|
|
38
|
+
module MQRPC
|
|
39
|
+
class Message
|
|
40
|
+
extend BindToHash
|
|
41
|
+
@@idseq = 0
|
|
42
|
+
@@idlock = Mutex.new
|
|
43
|
+
@@knowntypes = Hash.new
|
|
44
|
+
attr_accessor :data
|
|
45
|
+
|
|
46
|
+
# Message attributes
|
|
47
|
+
header :id
|
|
48
|
+
header :message_class
|
|
49
|
+
header :delayable
|
|
50
|
+
header :reply_to
|
|
51
|
+
header :timestamp
|
|
52
|
+
header :args
|
|
53
|
+
|
|
54
|
+
def self.inherited(subclass)
|
|
55
|
+
MQRPC::logger.debug "Message '#{subclass.name}' subclasses #{self.name}"
|
|
56
|
+
@@knowntypes[subclass.name] = subclass
|
|
57
|
+
|
|
58
|
+
# Call the class initializer if it has one.
|
|
59
|
+
if subclass.respond_to?(:class_initialize)
|
|
60
|
+
subclass.class_initialize
|
|
61
|
+
end
|
|
62
|
+
end # def self.inherited
|
|
63
|
+
|
|
64
|
+
def self.new_from_data(data)
|
|
65
|
+
obj = nil
|
|
66
|
+
name = data["message_class"]
|
|
67
|
+
if @@knowntypes.has_key?(name)
|
|
68
|
+
obj = @@knowntypes[name].new
|
|
69
|
+
else
|
|
70
|
+
$stderr.puts "No known message class: #{name}, #{data.inspect}"
|
|
71
|
+
obj = Message.new
|
|
72
|
+
end
|
|
73
|
+
obj.data = data
|
|
74
|
+
return obj
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def initialize
|
|
78
|
+
@data = Hash.new
|
|
79
|
+
# Don't delay messages by defualt
|
|
80
|
+
self.delayable = false
|
|
81
|
+
|
|
82
|
+
generate_id!
|
|
83
|
+
self.message_class = self.class.name
|
|
84
|
+
self.args = Hash.new
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def generate_id!
|
|
88
|
+
@@idlock.synchronize do
|
|
89
|
+
self.id = @@idseq
|
|
90
|
+
#puts "Generating id. #{self.class}.id == #{self.id}"
|
|
91
|
+
@@idseq += 1
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def age
|
|
96
|
+
return Time.now.to_f - timestamp
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def to_json(*args)
|
|
100
|
+
return @data.to_json(*args)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
protected
|
|
104
|
+
attr :data
|
|
105
|
+
end # class Message
|
|
106
|
+
|
|
107
|
+
class RequestMessage < Message
|
|
108
|
+
# Nothing.
|
|
109
|
+
end # class RequestMessage
|
|
110
|
+
|
|
111
|
+
class ResponseMessage < Message
|
|
112
|
+
header :in_reply_to
|
|
113
|
+
header :from_queue
|
|
114
|
+
|
|
115
|
+
def initialize(source_request=nil)
|
|
116
|
+
super()
|
|
117
|
+
|
|
118
|
+
# Copy the request id if we are given a source_request
|
|
119
|
+
if source_request.is_a?(RequestMessage)
|
|
120
|
+
self.in_reply_to = source_request.id
|
|
121
|
+
#self.delayable = source_request.delayable
|
|
122
|
+
end
|
|
123
|
+
self.args = Hash.new
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Report the success of the request this response is for.
|
|
127
|
+
# Should be implemented by subclasses.
|
|
128
|
+
def success?
|
|
129
|
+
raise NotImplementedError
|
|
130
|
+
end
|
|
131
|
+
end # class ResponseMessage
|
|
132
|
+
end # module MQRPC
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
***************
|
|
2
|
+
*** 108,113 ****
|
|
3
|
+
# Nothing.
|
|
4
|
+
end # class RequestMessage
|
|
5
|
+
|
|
6
|
+
class ResponseMessage < Message
|
|
7
|
+
header :in_reply_to
|
|
8
|
+
header :from_queue
|
|
9
|
+
--- 108,117 ----
|
|
10
|
+
# Nothing.
|
|
11
|
+
end # class RequestMessage
|
|
12
|
+
|
|
13
|
+
+ class DummyMessage < Message
|
|
14
|
+
+ # Nothing.
|
|
15
|
+
+ end # class DummyMessage
|
|
16
|
+
+
|
|
17
|
+
class ResponseMessage < Message
|
|
18
|
+
header :in_reply_to
|
|
19
|
+
header :from_queue
|
data/lib/mqrpc/operation.rb
CHANGED
|
@@ -6,9 +6,14 @@ module MQRPC
|
|
|
6
6
|
# A single message operation
|
|
7
7
|
# * Takes a callback to call when a message is received
|
|
8
8
|
# * Allows you to wait for the operation to complete.
|
|
9
|
-
# * An operation is 'complete' when the callback returns
|
|
9
|
+
# * An operation is 'complete' when the callback returns.
|
|
10
|
+
#
|
|
11
|
+
# If your callback returns :continue, then we will not call finished.
|
|
12
|
+
# This allows you to have an operation that is invoked multiple times,
|
|
13
|
+
# such as for streaming blocks of data, and only finish when you know
|
|
14
|
+
# you are done.
|
|
10
15
|
class Operation
|
|
11
|
-
def initialize(callback)
|
|
16
|
+
def initialize(&callback)
|
|
12
17
|
@mutex = Mutex.new
|
|
13
18
|
@callback = callback
|
|
14
19
|
@cv = ConditionVariable.new
|
|
@@ -21,9 +26,7 @@ module MQRPC
|
|
|
21
26
|
@mutex.synchronize do
|
|
22
27
|
ret = @callback.call(*args)
|
|
23
28
|
if ret != :continue
|
|
24
|
-
|
|
25
|
-
@finished = true
|
|
26
|
-
@cv.signal
|
|
29
|
+
_withlock_finished
|
|
27
30
|
end
|
|
28
31
|
return ret
|
|
29
32
|
end
|
|
@@ -34,15 +37,35 @@ module MQRPC
|
|
|
34
37
|
# immediately.
|
|
35
38
|
def wait_until_finished
|
|
36
39
|
@mutex.synchronize do
|
|
37
|
-
if !
|
|
40
|
+
if !_withlock_finished?
|
|
38
41
|
@cv.wait(@mutex)
|
|
39
42
|
end
|
|
40
43
|
end
|
|
41
44
|
end # def wait_until_finished
|
|
42
45
|
|
|
43
|
-
|
|
46
|
+
# Is the operation finished yet?
|
|
44
47
|
def finished?
|
|
48
|
+
@mutex.synchronize do
|
|
49
|
+
return _withlock_finished?
|
|
50
|
+
end
|
|
51
|
+
end # def finished?
|
|
52
|
+
|
|
53
|
+
# Declare that the operation is finished.
|
|
54
|
+
def finished
|
|
55
|
+
@mutex.synchronize do
|
|
56
|
+
return _withlock_finished
|
|
57
|
+
end
|
|
58
|
+
end # def finished
|
|
59
|
+
|
|
60
|
+
protected
|
|
61
|
+
def _withlock_finished?
|
|
45
62
|
return @finished
|
|
46
63
|
end # def finished?
|
|
64
|
+
|
|
65
|
+
def _withlock_finished
|
|
66
|
+
@finished = true
|
|
67
|
+
@cv.signal
|
|
68
|
+
end
|
|
69
|
+
|
|
47
70
|
end # class Operation
|
|
48
71
|
end # module MQRPC
|
data/lib/mqrpc/sizedhash.rb
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
require 'thread'
|
|
2
2
|
require 'mqrpc'
|
|
3
3
|
|
|
4
|
+
# A mutex which logs every enter/exit on synchronize
|
|
4
5
|
class TrackingMutex < Mutex
|
|
5
6
|
def synchronize(&blk)
|
|
6
|
-
|
|
7
|
+
MQRPC::logger.debug "Enter synchronize #{self} @ #{caller[0]}"
|
|
7
8
|
super { blk.call }
|
|
8
|
-
|
|
9
|
+
MQRPC::logger.debug "Exit synchronize #{self} @ #{caller[0]}"
|
|
9
10
|
end # def synchronize
|
|
10
11
|
end # clas TrackingMutex < Mutex
|
|
11
12
|
|
|
@@ -17,7 +18,7 @@ class SizedThreadSafeHash
|
|
|
17
18
|
attr_reader :size
|
|
18
19
|
|
|
19
20
|
def initialize(size, &callback)
|
|
20
|
-
@lock =
|
|
21
|
+
@lock = Mutex.new
|
|
21
22
|
@size = size
|
|
22
23
|
@condvar = ConditionVariable.new
|
|
23
24
|
@data = Hash.new
|
|
@@ -30,7 +31,7 @@ class SizedThreadSafeHash
|
|
|
30
31
|
@lock.synchronize do
|
|
31
32
|
# If adding a new item, wait if the hash is full
|
|
32
33
|
if !@data.has_key?(key) and _withlock_full?
|
|
33
|
-
MQRPC::logger.info "#{self}: Waiting to add key #{key.inspect}, hash is full (
|
|
34
|
+
MQRPC::logger.info "#{self}: Waiting to add key #{key.inspect}, hash is full (thread #{Thread.current})"
|
|
34
35
|
if @state != :blocked
|
|
35
36
|
@state = :blocked
|
|
36
37
|
@callback.call(@state) if @callback
|
data/lib/mqrpc/test.diff
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Index: lib/mqrpc/agent.rb
|
|
2
|
+
===================================================================
|
|
3
|
+
--- agent.rb (revision 318)
|
|
4
|
+
+++ agent.rb (working copy)
|
|
5
|
+
@@ -267,10 +267,16 @@
|
|
6
|
+
end
|
|
7
|
+
MQRPC::logger.info "Subscribing to queue #{name}"
|
|
8
|
+
@queues << name
|
|
9
|
+
+ # Send a dummy message to queue #{name} so there's at least
|
|
10
|
+
+ # one message to receive, and wake up our Operation.
|
|
11
|
+
+ sendmsg(name, DummyMessage.new)
|
|
12
|
+
exchange = @mq.topic(@config.mqexchange, :durable => true)
|
|
13
|
+
mq_q = @mq.queue(name, :durable => true)
|
|
14
|
+
mq_q.bind(exchange, :key => "*")
|
|
15
|
+
+ op = Operation.new
|
|
16
|
+
mq_q.subscribe(:ack => true) do |hdr, msg|
|
|
17
|
+
+ op.finished
|
|
18
|
+
+ return if msg.is_a?(DummyMessage)
|
|
19
|
+
queue = hdr.routing_key
|
|
20
|
+
MQRPC::logger.info("received message on #{queue}")
|
|
21
|
+
@receive_queue << [hdr, msg]
|
|
22
|
+
@@ -278,6 +284,10 @@
|
|
23
|
+
MQRPC::logger.info("msg: #{msg}")
|
|
24
|
+
MQRPC::logger.info("#{queue} queue size: #{@receive_queue.length}")
|
|
25
|
+
end
|
|
26
|
+
+ # Wait until we receive our first message (might be DummyMessage,
|
|
27
|
+
+ # doesn't matter) -- this confirms we are subscribed. subscribe
|
|
28
|
+
+ # is async...
|
|
29
|
+
+ op.wait_until_finished
|
|
30
|
+
when :topic
|
|
31
|
+
MQRPC::logger.info "Subscribing to topic #{name}"
|
|
32
|
+
exchange = @mq.topic(@config.mqexchange, :durable => true)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mqrpc
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jordan Sissel, Pete Fritchman
|
|
@@ -9,7 +9,7 @@ autorequire:
|
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
|
|
12
|
-
date: 2009-11-
|
|
12
|
+
date: 2009-11-20 00:00:00 -08:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
@@ -53,12 +53,15 @@ extra_rdoc_files: []
|
|
|
53
53
|
files:
|
|
54
54
|
- lib/mqrpc/agent.rb
|
|
55
55
|
- lib/mqrpc/config.rb
|
|
56
|
+
- lib/mqrpc/test.diff
|
|
56
57
|
- lib/mqrpc/logger.rb
|
|
57
58
|
- lib/mqrpc/functions/ping.rb
|
|
58
59
|
- lib/mqrpc/message.rb
|
|
60
|
+
- lib/mqrpc/message.rb.orig
|
|
59
61
|
- lib/mqrpc/operation.rb
|
|
60
62
|
- lib/mqrpc/messages/ping.rb
|
|
61
63
|
- lib/mqrpc/sizedhash.rb
|
|
64
|
+
- lib/mqrpc/message.rb.rej
|
|
62
65
|
- lib/mqrpc.rb
|
|
63
66
|
has_rdoc: true
|
|
64
67
|
homepage: http://code.google.com/p/logstash/wiki/MQRPC
|