bunny 0.5.1 → 0.5.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/bunny.gemspec +2 -2
- data/examples/simple_08.rb +1 -1
- data/examples/simple_09.rb +1 -1
- data/examples/simple_ack_08.rb +1 -1
- data/examples/simple_ack_09.rb +1 -1
- data/examples/simple_consumer_08.rb +15 -9
- data/examples/simple_consumer_09.rb +15 -9
- data/examples/simple_fanout_08.rb +1 -1
- data/examples/simple_fanout_09.rb +1 -1
- data/examples/simple_headers_08.rb +1 -1
- data/examples/simple_headers_09.rb +1 -1
- data/examples/simple_publisher_08.rb +2 -2
- data/examples/simple_topic_08.rb +1 -1
- data/examples/simple_topic_09.rb +1 -1
- data/lib/bunny.rb +1 -1
- data/lib/bunny/client08.rb +115 -51
- data/lib/bunny/client09.rb +117 -53
- data/lib/bunny/queue08.rb +19 -5
- data/lib/bunny/queue09.rb +19 -5
- data/lib/qrack/client.rb +2 -2
- data/spec/spec_08/bunny_spec.rb +23 -4
- data/spec/spec_08/exchange_spec.rb +31 -23
- data/spec/spec_08/queue_spec.rb +4 -4
- data/spec/spec_09/bunny_spec.rb +23 -4
- data/spec/spec_09/exchange_spec.rb +31 -23
- data/spec/spec_09/queue_spec.rb +4 -4
- metadata +2 -2
data/bunny.gemspec
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = %q{bunny}
|
3
|
-
s.version = "0.5.
|
3
|
+
s.version = "0.5.2"
|
4
4
|
s.authors = ["Chris Duncan"]
|
5
|
-
s.date = %q{2009-08-
|
5
|
+
s.date = %q{2009-08-17}
|
6
6
|
s.description = %q{Another synchronous Ruby AMQP client}
|
7
7
|
s.email = %q{celldee@gmail.com}
|
8
8
|
s.rubyforge_project = %q{bunny-amqp}
|
data/examples/simple_08.rb
CHANGED
data/examples/simple_09.rb
CHANGED
data/examples/simple_ack_08.rb
CHANGED
data/examples/simple_ack_09.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# simple_consumer_08.rb
|
2
2
|
|
3
3
|
# N.B. To be used in conjunction with simple_publisher.rb
|
4
4
|
|
@@ -13,15 +13,18 @@
|
|
13
13
|
#
|
14
14
|
# Open up two console windows start this program in one of them by typing -
|
15
15
|
#
|
16
|
-
# ruby
|
16
|
+
# ruby simple_consumer_08.rb
|
17
17
|
#
|
18
18
|
# Then switch to the other console window and type -
|
19
19
|
#
|
20
|
-
# ruby
|
20
|
+
# ruby simple_publisher_08.rb
|
21
21
|
#
|
22
22
|
# A message will be printed out by the simple_consumer and it will wait for the next message
|
23
|
+
# until the timeout interval is reached.
|
23
24
|
#
|
24
|
-
# Run simple_publisher
|
25
|
+
# Run simple_publisher as many times as you like. When you want the program to stop just stop
|
26
|
+
# sending messages and the subscribe loop will timeout after 30 seconds, the program will
|
27
|
+
# unsubscribe from the queue and close the connection to the server.
|
25
28
|
|
26
29
|
$:.unshift File.dirname(__FILE__) + '/../lib'
|
27
30
|
|
@@ -45,11 +48,14 @@ q.bind(exch, :key => 'fred')
|
|
45
48
|
i = 1
|
46
49
|
|
47
50
|
# subscribe to queue
|
48
|
-
q.subscribe(:consumer_tag => 'testtag1') do |msg|
|
49
|
-
puts i.to_s
|
51
|
+
ret = q.subscribe(:consumer_tag => 'testtag1', :timeout => 30) do |msg|
|
52
|
+
puts "#{i.to_s}: #{msg}"
|
50
53
|
i+=1
|
51
|
-
q.unsubscribe(:consumer_tag => 'testtag1') if i == 5
|
52
54
|
end
|
53
55
|
|
54
|
-
|
55
|
-
|
56
|
+
if ret == :timed_out
|
57
|
+
puts '==== simple_consumer_08.rb timed out - closing down ===='
|
58
|
+
q.unsubscribe(:consumer_tag => 'testtag1')
|
59
|
+
# close the connection
|
60
|
+
b.stop
|
61
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# simple_consumer_09.rb
|
2
2
|
|
3
3
|
# N.B. To be used in conjunction with simple_publisher.rb
|
4
4
|
|
@@ -13,15 +13,18 @@
|
|
13
13
|
#
|
14
14
|
# Open up two console windows start this program in one of them by typing -
|
15
15
|
#
|
16
|
-
# ruby
|
16
|
+
# ruby simple_consumer_09.rb
|
17
17
|
#
|
18
18
|
# Then switch to the other console window and type -
|
19
19
|
#
|
20
|
-
# ruby
|
20
|
+
# ruby simple_publisher_09.rb
|
21
21
|
#
|
22
22
|
# A message will be printed out by the simple_consumer and it will wait for the next message
|
23
|
+
# until the timeout interval is reached.
|
23
24
|
#
|
24
|
-
# Run simple_publisher
|
25
|
+
# Run simple_publisher as many times as you like. When you want the program to stop just stop
|
26
|
+
# sending messages and the subscribe loop will timeout after 30 seconds, the program will
|
27
|
+
# unsubscribe from the queue and close the connection to the server.
|
25
28
|
|
26
29
|
$:.unshift File.dirname(__FILE__) + '/../lib'
|
27
30
|
|
@@ -45,11 +48,14 @@ q.bind(exch, :key => 'fred')
|
|
45
48
|
i = 1
|
46
49
|
|
47
50
|
# subscribe to queue
|
48
|
-
q.subscribe(:consumer_tag => 'testtag1') do |msg|
|
49
|
-
puts i.to_s
|
51
|
+
ret = q.subscribe(:consumer_tag => 'testtag1', :timeout => 30) do |msg|
|
52
|
+
puts "#{i.to_s}: #{msg}"
|
50
53
|
i+=1
|
51
|
-
q.unsubscribe(:consumer_tag => 'testtag1') if i == 5
|
52
54
|
end
|
53
55
|
|
54
|
-
|
55
|
-
|
56
|
+
if ret == :timed_out
|
57
|
+
puts '==== simple_consumer_09.rb timed out - closing down ===='
|
58
|
+
q.unsubscribe(:consumer_tag => 'testtag1')
|
59
|
+
# close the connection
|
60
|
+
b.stop
|
61
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
# simple_publisher_08.rb
|
2
2
|
|
3
|
-
# N.B. To be used in conjunction with
|
3
|
+
# N.B. To be used in conjunction with simple_consumer_08.rb. See simple_consumer.rb for explanation.
|
4
4
|
|
5
5
|
# Assumes that target message broker/server has a user called 'guest' with a password 'guest'
|
6
6
|
# and that it is running on 'localhost'.
|
data/examples/simple_topic_08.rb
CHANGED
data/examples/simple_topic_09.rb
CHANGED
data/lib/bunny.rb
CHANGED
data/lib/bunny/client08.rb
CHANGED
@@ -34,6 +34,9 @@ Sets up a Bunny::Client object ready for connection to a broker/server. _Client_
|
|
34
34
|
servers, the server may respond to a Connection::Open method with a Connection::Redirect. The insist
|
35
35
|
option, if set to _true_, tells the server that the client is insisting on a connection to the
|
36
36
|
specified server.
|
37
|
+
* <tt>:frame_max => maximum frame size in bytes (default = 131072)</tt>
|
38
|
+
* <tt>:channel_max => maximum number of channels (default = 0 no maximum)</tt>
|
39
|
+
* <tt>:heartbeat => number of seconds (default = 0 no heartbeat)</tt>
|
37
40
|
|
38
41
|
=end
|
39
42
|
|
@@ -50,10 +53,16 @@ Sets up a Bunny::Client object ready for connection to a broker/server. _Client_
|
|
50
53
|
@status = :not_connected
|
51
54
|
@frame_max = opts[:frame_max] || 131072
|
52
55
|
@channel_max = opts[:channel_max] || 0
|
56
|
+
@heartbeat = opts[:heartbeat] || 0
|
53
57
|
@logger = nil
|
54
58
|
create_logger if @logging
|
59
|
+
@channels = []
|
55
60
|
# Create channel 0
|
56
61
|
@channel = Bunny::Channel.new(self, true)
|
62
|
+
@exchanges = {}
|
63
|
+
@queues = {}
|
64
|
+
@heartbeat_in = false
|
65
|
+
@connecting = false
|
57
66
|
end
|
58
67
|
|
59
68
|
=begin rdoc
|
@@ -91,18 +100,6 @@ Exchange
|
|
91
100
|
|
92
101
|
=== DESCRIPTION:
|
93
102
|
|
94
|
-
Returns hash of exchanges declared by Bunny.
|
95
|
-
|
96
|
-
=end
|
97
|
-
|
98
|
-
def exchanges
|
99
|
-
@exchanges ||= {}
|
100
|
-
end
|
101
|
-
|
102
|
-
=begin rdoc
|
103
|
-
|
104
|
-
=== DESCRIPTION:
|
105
|
-
|
106
103
|
Declares a queue to the broker/server. If the queue does not exist, a new one is created
|
107
104
|
using the arguments passed in. If the queue already exists, a reference to it is created, provided
|
108
105
|
that the arguments passed in do not conflict with the existing attributes of the queue. If an error
|
@@ -141,19 +138,16 @@ Queue
|
|
141
138
|
|
142
139
|
return queues[name] if queues.has_key?(name)
|
143
140
|
|
144
|
-
|
141
|
+
Bunny::Queue.new(self, name, opts)
|
145
142
|
end
|
146
|
-
|
147
|
-
=begin rdoc
|
148
|
-
|
149
|
-
=== DESCRIPTION:
|
150
|
-
|
151
|
-
Returns hash of queues declared by Bunny.
|
152
|
-
|
153
|
-
=end
|
154
143
|
|
155
|
-
def
|
156
|
-
|
144
|
+
def send_heartbeat
|
145
|
+
# Create a new heartbeat frame
|
146
|
+
hb = Qrack::Transport::Heartbeat.new('')
|
147
|
+
# Channel 0 must be used
|
148
|
+
switch_channel(0) if @channel.number > 0
|
149
|
+
# Send the heartbeat to server
|
150
|
+
send_frame(hb)
|
157
151
|
end
|
158
152
|
|
159
153
|
def send_frame(*args)
|
@@ -169,18 +163,72 @@ Returns hash of queues declared by Bunny.
|
|
169
163
|
nil
|
170
164
|
end
|
171
165
|
|
172
|
-
def next_frame
|
173
|
-
|
174
|
-
|
175
|
-
|
166
|
+
def next_frame(opts = {})
|
167
|
+
secs = opts[:timeout] || 0
|
168
|
+
|
169
|
+
begin
|
170
|
+
Timeout::timeout(secs) do
|
171
|
+
@frame = Qrack::Transport::Frame.parse(buffer)
|
172
|
+
end
|
173
|
+
rescue Timeout::Error
|
174
|
+
return :timed_out
|
175
|
+
end
|
176
|
+
|
177
|
+
@logger.info("received") { @frame } if @logging
|
178
|
+
|
179
|
+
raise Bunny::ConnectionError, 'No connection to server' if (@frame.nil? and !connecting?)
|
180
|
+
|
181
|
+
if @frame.is_a?(Qrack::Transport::Heartbeat)
|
182
|
+
@heartbeat_in = true
|
183
|
+
next_frame
|
184
|
+
end
|
185
|
+
|
186
|
+
@frame
|
176
187
|
end
|
177
188
|
|
178
189
|
def next_payload
|
179
|
-
frame = next_frame
|
190
|
+
frame = next_frame
|
180
191
|
frame.payload
|
181
192
|
end
|
182
193
|
|
183
194
|
alias next_method next_payload
|
195
|
+
|
196
|
+
=begin rdoc
|
197
|
+
|
198
|
+
=== DESCRIPTION:
|
199
|
+
|
200
|
+
Checks to see whether or not an undeliverable message has been returned as a result of a publish
|
201
|
+
with the <tt>:immediate</tt> or <tt>:mandatory</tt> options.
|
202
|
+
|
203
|
+
==== OPTIONS:
|
204
|
+
|
205
|
+
* <tt>:timeout => number of seconds (default = 0.1) - The method will wait for a return
|
206
|
+
message until this timeout interval is reached.
|
207
|
+
|
208
|
+
==== RETURNS:
|
209
|
+
|
210
|
+
<tt>:no_return</tt> if message was not returned before timeout .
|
211
|
+
<tt>{:header, :return_details, :payload}</tt> if message is returned. <tt>:return_details</tt> is
|
212
|
+
a hash <tt>{:reply_code, :reply_text, :exchange, :routing_key}</tt>.
|
213
|
+
|
214
|
+
=end
|
215
|
+
|
216
|
+
def returned_message(opts = {})
|
217
|
+
secs = opts[:timeout] || 0.1
|
218
|
+
frame = next_frame(:timeout => secs)
|
219
|
+
|
220
|
+
if frame.is_a?(Symbol)
|
221
|
+
return :no_return if frame == :timed_out
|
222
|
+
end
|
223
|
+
|
224
|
+
method = frame.payload
|
225
|
+
header = next_payload
|
226
|
+
msg = next_payload
|
227
|
+
raise Bunny::MessageError, 'unexpected length' if msg.length < header.size
|
228
|
+
|
229
|
+
# Return the message and related info
|
230
|
+
{:header => header, :payload => msg, :return_details => method.arguments}
|
231
|
+
end
|
184
232
|
|
185
233
|
=begin rdoc
|
186
234
|
|
@@ -197,12 +245,9 @@ _Bunny_::_ProtocolError_ is raised. If successful, _Client_._status_ is set to <
|
|
197
245
|
|
198
246
|
def close
|
199
247
|
# Close all active channels
|
200
|
-
channels.
|
248
|
+
channels.each do |c|
|
201
249
|
c.close if c.open?
|
202
250
|
end
|
203
|
-
|
204
|
-
# Set client channel to zero
|
205
|
-
self.channel = channels[0]
|
206
251
|
|
207
252
|
# Close connection to AMQP server
|
208
253
|
close_connection
|
@@ -235,6 +280,8 @@ _Bunny_::_ProtocolError_ is raised. If successful, _Client_._status_ is set to <
|
|
235
280
|
=end
|
236
281
|
|
237
282
|
def start_session
|
283
|
+
@connecting = true
|
284
|
+
|
238
285
|
loop do
|
239
286
|
# Create/get socket
|
240
287
|
socket
|
@@ -246,15 +293,17 @@ _Bunny_::_ProtocolError_ is raised. If successful, _Client_._status_ is set to <
|
|
246
293
|
break if open_connection == :ok
|
247
294
|
end
|
248
295
|
|
249
|
-
# Open
|
250
|
-
|
251
|
-
|
296
|
+
# Open another channel because channel zero is used for specific purposes
|
297
|
+
c = create_channel()
|
298
|
+
c.open
|
252
299
|
|
253
300
|
# Get access ticket
|
254
301
|
request_access
|
255
302
|
|
303
|
+
@connecting = false
|
304
|
+
|
256
305
|
# return status
|
257
|
-
status
|
306
|
+
@status = :connected
|
258
307
|
end
|
259
308
|
|
260
309
|
alias start start_session
|
@@ -263,7 +312,7 @@ _Bunny_::_ProtocolError_ is raised. If successful, _Client_._status_ is set to <
|
|
263
312
|
|
264
313
|
=== DESCRIPTION:
|
265
314
|
|
266
|
-
Asks the broker to redeliver all unacknowledged messages on a
|
315
|
+
Asks the broker to redeliver all unacknowledged messages on a specified channel. Zero or
|
267
316
|
more messages may be redelivered.
|
268
317
|
|
269
318
|
==== Options:
|
@@ -388,23 +437,36 @@ after a rollback.
|
|
388
437
|
@logging = bool
|
389
438
|
create_logger if @logging
|
390
439
|
end
|
391
|
-
|
392
|
-
def channels
|
393
|
-
@channels ||= {}
|
394
|
-
end
|
395
440
|
|
396
|
-
def
|
397
|
-
channels.
|
441
|
+
def create_channel
|
442
|
+
channels.each do |c|
|
398
443
|
return c if (!c.open? and c.number != 0)
|
399
444
|
end
|
400
445
|
# If no channel to re-use instantiate new one
|
401
446
|
Bunny::Channel.new(self)
|
402
447
|
end
|
403
448
|
|
449
|
+
def switch_channel(chann)
|
450
|
+
if (0...channels.size).include? chann
|
451
|
+
@channel = channels[chann]
|
452
|
+
chann
|
453
|
+
else
|
454
|
+
raise RuntimeError, "Invalid channel number - #{chann}"
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
def connecting?
|
459
|
+
connecting
|
460
|
+
end
|
461
|
+
|
404
462
|
def init_connection
|
405
463
|
write(Qrack::Protocol::HEADER)
|
406
464
|
write([1, 1, Qrack::Protocol::VERSION_MAJOR, Qrack::Protocol::VERSION_MINOR].pack('C4'))
|
407
|
-
|
465
|
+
|
466
|
+
frame = next_frame
|
467
|
+
if frame.nil? or !frame.payload.is_a?(Qrack::Protocol::Connection::Start)
|
468
|
+
raise Bunny::ProtocolError, 'Connection initiation failed'
|
469
|
+
end
|
408
470
|
end
|
409
471
|
|
410
472
|
def open_connection
|
@@ -417,12 +479,14 @@ after a rollback.
|
|
417
479
|
)
|
418
480
|
)
|
419
481
|
|
420
|
-
|
421
|
-
|
482
|
+
frame = next_frame
|
483
|
+
raise Bunny::ProtocolError, "Connection failed - user: #{@user}, pass: #{@pass}" if frame.nil?
|
484
|
+
|
485
|
+
method = frame.payload
|
422
486
|
|
423
487
|
if method.is_a?(Qrack::Protocol::Connection::Tune)
|
424
488
|
send_frame(
|
425
|
-
Qrack::Protocol::Connection::TuneOk.new( :channel_max => @channel_max, :frame_max => @frame_max, :heartbeat =>
|
489
|
+
Qrack::Protocol::Connection::TuneOk.new( :channel_max => @channel_max, :frame_max => @frame_max, :heartbeat => @heartbeat)
|
426
490
|
)
|
427
491
|
end
|
428
492
|
|
@@ -444,6 +508,9 @@ after a rollback.
|
|
444
508
|
end
|
445
509
|
|
446
510
|
def close_connection
|
511
|
+
# Set client channel to zero
|
512
|
+
switch_channel(0)
|
513
|
+
|
447
514
|
send_frame(
|
448
515
|
Qrack::Protocol::Connection::Close.new(:reply_code => 200, :reply_text => 'Goodbye', :class_id => 0, :method_id => 0)
|
449
516
|
)
|
@@ -477,9 +544,7 @@ after a rollback.
|
|
477
544
|
def socket
|
478
545
|
return @socket if @socket and (@status == :connected) and not @socket.closed?
|
479
546
|
|
480
|
-
begin
|
481
|
-
@status = :not_connected
|
482
|
-
|
547
|
+
begin
|
483
548
|
# Attempt to connect.
|
484
549
|
@socket = timeout(CONNECT_TIMEOUT) do
|
485
550
|
TCPSocket.new(host, port)
|
@@ -488,7 +553,6 @@ after a rollback.
|
|
488
553
|
if Socket.constants.include? 'TCP_NODELAY'
|
489
554
|
@socket.setsockopt Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1
|
490
555
|
end
|
491
|
-
@status = :connected
|
492
556
|
rescue => e
|
493
557
|
@status = :not_connected
|
494
558
|
raise Bunny::ServerDownError, e.message
|