bunny 0.5.2 → 0.5.3
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 +4 -2
- data/examples/simple_consumer_08.rb +6 -6
- data/examples/simple_consumer_09.rb +6 -6
- data/lib/bunny.rb +1 -1
- data/lib/bunny/channel08.rb +3 -8
- data/lib/bunny/channel09.rb +3 -8
- data/lib/bunny/client08.rb +217 -344
- data/lib/bunny/client09.rb +175 -301
- data/lib/bunny/exchange08.rb +6 -1
- data/lib/bunny/exchange09.rb +6 -1
- data/lib/bunny/queue08.rb +144 -170
- data/lib/bunny/queue09.rb +160 -185
- data/lib/qrack/channel.rb +18 -0
- data/lib/qrack/client.rb +175 -2
- data/lib/qrack/qrack08.rb +2 -0
- data/lib/qrack/qrack09.rb +2 -0
- data/lib/qrack/queue.rb +53 -0
- data/spec/spec_08/exchange_spec.rb +8 -1
- data/spec/spec_08/queue_spec.rb +26 -0
- data/spec/spec_09/exchange_spec.rb +8 -1
- data/spec/spec_09/queue_spec.rb +26 -0
- metadata +4 -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.3"
|
4
4
|
s.authors = ["Chris Duncan"]
|
5
|
-
s.date = %q{2009-
|
5
|
+
s.date = %q{2009-09-07}
|
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}
|
@@ -39,6 +39,8 @@ Gem::Specification.new do |s|
|
|
39
39
|
"lib/bunny/queue08.rb",
|
40
40
|
"lib/bunny/queue09.rb",
|
41
41
|
"lib/qrack/client.rb",
|
42
|
+
"lib/qrack/channel.rb",
|
43
|
+
"lib/qrack/queue.rb",
|
42
44
|
"lib/qrack/protocol/protocol08.rb",
|
43
45
|
"lib/qrack/protocol/protocol09.rb",
|
44
46
|
"lib/qrack/protocol/spec08.rb",
|
@@ -48,12 +48,12 @@ q.bind(exch, :key => 'fred')
|
|
48
48
|
i = 1
|
49
49
|
|
50
50
|
# subscribe to queue
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
51
|
+
begin
|
52
|
+
ret = q.subscribe(:consumer_tag => 'testtag1', :timeout => 30) do |msg|
|
53
|
+
puts "#{i.to_s}: #{msg}"
|
54
|
+
i+=1
|
55
|
+
end
|
56
|
+
rescue Qrack::ClientTimeout
|
57
57
|
puts '==== simple_consumer_08.rb timed out - closing down ===='
|
58
58
|
q.unsubscribe(:consumer_tag => 'testtag1')
|
59
59
|
# close the connection
|
@@ -48,12 +48,12 @@ q.bind(exch, :key => 'fred')
|
|
48
48
|
i = 1
|
49
49
|
|
50
50
|
# subscribe to queue
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
51
|
+
begin
|
52
|
+
ret = q.subscribe(:consumer_tag => 'testtag1', :timeout => 30) do |msg|
|
53
|
+
puts "#{i.to_s}: #{msg}"
|
54
|
+
i+=1
|
55
|
+
end
|
56
|
+
rescue Qrack::ClientTimeout
|
57
57
|
puts '==== simple_consumer_09.rb timed out - closing down ===='
|
58
58
|
q.unsubscribe(:consumer_tag => 'testtag1')
|
59
59
|
# close the connection
|
data/lib/bunny.rb
CHANGED
data/lib/bunny/channel08.rb
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
module Bunny
|
2
|
-
class Channel
|
3
|
-
attr_accessor :number, :active
|
4
|
-
attr_reader :client
|
2
|
+
class Channel < Qrack::Channel
|
5
3
|
|
6
|
-
def initialize(client
|
7
|
-
|
8
|
-
zero ? @number = 0 : @number = client.channels.size
|
9
|
-
@active = false
|
10
|
-
client.channels[@number] ||= self
|
4
|
+
def initialize(client)
|
5
|
+
super
|
11
6
|
end
|
12
7
|
|
13
8
|
def open
|
data/lib/bunny/channel09.rb
CHANGED
@@ -1,13 +1,8 @@
|
|
1
1
|
module Bunny
|
2
|
-
class Channel09
|
3
|
-
attr_accessor :number, :active
|
4
|
-
attr_reader :client
|
2
|
+
class Channel09 < Qrack::Channel
|
5
3
|
|
6
|
-
def initialize(client
|
7
|
-
|
8
|
-
zero ? @number = 0 : @number = client.channels.size
|
9
|
-
@active = false
|
10
|
-
client.channels[@number] ||= self
|
4
|
+
def initialize(client)
|
5
|
+
super
|
11
6
|
end
|
12
7
|
|
13
8
|
def open
|
data/lib/bunny/client08.rb
CHANGED
@@ -41,30 +41,30 @@ Sets up a Bunny::Client object ready for connection to a broker/server. _Client_
|
|
41
41
|
=end
|
42
42
|
|
43
43
|
def initialize(opts = {})
|
44
|
+
super
|
44
45
|
@spec = '0-8'
|
45
|
-
@host = opts[:host] || 'localhost'
|
46
46
|
@port = opts[:port] || Qrack::Protocol::PORT
|
47
|
-
@user = opts[:user] || 'guest'
|
48
|
-
@pass = opts[:pass] || 'guest'
|
49
|
-
@vhost = opts[:vhost] || '/'
|
50
|
-
@logfile = opts[:logfile] || nil
|
51
|
-
@logging = opts[:logging] || false
|
52
47
|
@insist = opts[:insist]
|
53
|
-
@status = :not_connected
|
54
|
-
@frame_max = opts[:frame_max] || 131072
|
55
|
-
@channel_max = opts[:channel_max] || 0
|
56
|
-
@heartbeat = opts[:heartbeat] || 0
|
57
|
-
@logger = nil
|
58
|
-
create_logger if @logging
|
59
|
-
@channels = []
|
60
|
-
# Create channel 0
|
61
|
-
@channel = Bunny::Channel.new(self, true)
|
62
|
-
@exchanges = {}
|
63
|
-
@queues = {}
|
64
|
-
@heartbeat_in = false
|
65
|
-
@connecting = false
|
66
48
|
end
|
67
49
|
|
50
|
+
def close_connection
|
51
|
+
# Set client channel to zero
|
52
|
+
switch_channel(0)
|
53
|
+
|
54
|
+
send_frame(
|
55
|
+
Qrack::Protocol::Connection::Close.new(:reply_code => 200, :reply_text => 'Goodbye', :class_id => 0, :method_id => 0)
|
56
|
+
)
|
57
|
+
raise Bunny::ProtocolError, "Error closing connection" unless next_method.is_a?(Qrack::Protocol::Connection::CloseOk)
|
58
|
+
end
|
59
|
+
|
60
|
+
def create_channel
|
61
|
+
channels.each do |c|
|
62
|
+
return c if (!c.open? and c.number != 0)
|
63
|
+
end
|
64
|
+
# If no channel to re-use instantiate new one
|
65
|
+
Bunny::Channel.new(self)
|
66
|
+
end
|
67
|
+
|
68
68
|
=begin rdoc
|
69
69
|
|
70
70
|
=== DESCRIPTION:
|
@@ -95,6 +95,135 @@ Exchange
|
|
95
95
|
return exchanges[name] if exchanges.has_key?(name)
|
96
96
|
Bunny::Exchange.new(self, name, opts)
|
97
97
|
end
|
98
|
+
|
99
|
+
def init_connection
|
100
|
+
write(Qrack::Protocol::HEADER)
|
101
|
+
write([1, 1, Qrack::Protocol::VERSION_MAJOR, Qrack::Protocol::VERSION_MINOR].pack('C4'))
|
102
|
+
|
103
|
+
frame = next_frame
|
104
|
+
if frame.nil? or !frame.payload.is_a?(Qrack::Protocol::Connection::Start)
|
105
|
+
raise Bunny::ProtocolError, 'Connection initiation failed'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def next_frame(opts = {})
|
110
|
+
frame = nil
|
111
|
+
|
112
|
+
case
|
113
|
+
when channel.frame_buffer.size > 0
|
114
|
+
frame = channel.frame_buffer.shift
|
115
|
+
when opts.has_key?(:timeout)
|
116
|
+
Timeout::timeout(opts[:timeout], Qrack::ClientTimeout) do
|
117
|
+
frame = Qrack::Transport::Frame.parse(buffer)
|
118
|
+
end
|
119
|
+
else
|
120
|
+
frame = Qrack::Transport::Frame.parse(buffer)
|
121
|
+
end
|
122
|
+
|
123
|
+
@logger.info("received") { frame } if @logging
|
124
|
+
|
125
|
+
raise Bunny::ConnectionError, 'No connection to server' if (frame.nil? and !connecting?)
|
126
|
+
|
127
|
+
# Monitor server activity and discard heartbeats
|
128
|
+
@message_in = true
|
129
|
+
|
130
|
+
case
|
131
|
+
when frame.is_a?(Qrack::Transport::Heartbeat)
|
132
|
+
next_frame(opts)
|
133
|
+
when frame.nil?
|
134
|
+
frame
|
135
|
+
when ((frame.channel != channel.number) and (frame.channel != 0))
|
136
|
+
channel.frame_buffer << frame
|
137
|
+
next_frame(opts)
|
138
|
+
else
|
139
|
+
frame
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
def open_connection
|
145
|
+
send_frame(
|
146
|
+
Qrack::Protocol::Connection::StartOk.new(
|
147
|
+
{:platform => 'Ruby', :product => 'Bunny', :information => 'http://github.com/celldee/bunny', :version => VERSION},
|
148
|
+
'AMQPLAIN',
|
149
|
+
{:LOGIN => @user, :PASSWORD => @pass},
|
150
|
+
'en_US'
|
151
|
+
)
|
152
|
+
)
|
153
|
+
|
154
|
+
frame = next_frame
|
155
|
+
raise Bunny::ProtocolError, "Connection failed - user: #{@user}, pass: #{@pass}" if frame.nil?
|
156
|
+
|
157
|
+
method = frame.payload
|
158
|
+
|
159
|
+
if method.is_a?(Qrack::Protocol::Connection::Tune)
|
160
|
+
send_frame(
|
161
|
+
Qrack::Protocol::Connection::TuneOk.new( :channel_max => @channel_max, :frame_max => @frame_max, :heartbeat => @heartbeat)
|
162
|
+
)
|
163
|
+
end
|
164
|
+
|
165
|
+
send_frame(
|
166
|
+
Qrack::Protocol::Connection::Open.new(:virtual_host => @vhost, :capabilities => '', :insist => @insist)
|
167
|
+
)
|
168
|
+
|
169
|
+
case method = next_method
|
170
|
+
when Qrack::Protocol::Connection::OpenOk
|
171
|
+
return :ok
|
172
|
+
when Qrack::Protocol::Connection::Redirect
|
173
|
+
raise Bunny::ConnectionError, "Cannot connect to the specified server - host: #{@host}, port: #{@port}" if @insist
|
174
|
+
|
175
|
+
@host, @port = method.host.split(':')
|
176
|
+
close_socket
|
177
|
+
else
|
178
|
+
raise Bunny::ProtocolError, 'Cannot open connection'
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
=begin rdoc
|
183
|
+
|
184
|
+
=== DESCRIPTION:
|
185
|
+
|
186
|
+
Requests a specific quality of service. The QoS can be specified for the current channel
|
187
|
+
or for all channels on the connection. The particular properties and semantics of a QoS
|
188
|
+
method always depend on the content class semantics. Though the QoS method could in principle
|
189
|
+
apply to both peers, it is currently meaningful only for the server.
|
190
|
+
|
191
|
+
==== Options:
|
192
|
+
|
193
|
+
* <tt>:prefetch_size => size in no. of octets (default = 0)</tt> - The client can request that
|
194
|
+
messages be sent in advance so that when the client finishes processing a message, the following
|
195
|
+
message is already held locally, rather than needing to be sent down the channel. Prefetching gives
|
196
|
+
a performance improvement. This field specifies the prefetch window size in octets. The server
|
197
|
+
will send a message in advance if it is equal to or smaller in size than the available prefetch
|
198
|
+
size (and also falls into other prefetch limits). May be set to zero, meaning "no specific limit",
|
199
|
+
although other prefetch limits may still apply. The prefetch-size is ignored if the no-ack option
|
200
|
+
is set.
|
201
|
+
* <tt>:prefetch_count => no. messages (default = 1)</tt> - Specifies a prefetch window in terms
|
202
|
+
of whole messages. This field may be used in combination with the prefetch-size field; a message
|
203
|
+
will only be sent in advance if both prefetch windows (and those at the channel and connection level)
|
204
|
+
allow it. The prefetch-count is ignored if the no-ack option is set.
|
205
|
+
* <tt>:global => true or false (_default_)</tt> - By default the QoS settings apply to the current channel only. If set to
|
206
|
+
true, they are applied to the entire connection.
|
207
|
+
|
208
|
+
==== RETURNS:
|
209
|
+
|
210
|
+
<tt>:qos_ok</tt> if successful.
|
211
|
+
|
212
|
+
=end
|
213
|
+
|
214
|
+
def qos(opts = {})
|
215
|
+
|
216
|
+
send_frame(
|
217
|
+
Qrack::Protocol::Basic::Qos.new({ :prefetch_size => 0, :prefetch_count => 1, :global => false }.merge(opts))
|
218
|
+
)
|
219
|
+
|
220
|
+
raise Bunny::ProtocolError,
|
221
|
+
"Error specifying Quality of Service" unless
|
222
|
+
next_method.is_a?(Qrack::Protocol::Basic::QosOk)
|
223
|
+
|
224
|
+
# return confirmation
|
225
|
+
:qos_ok
|
226
|
+
end
|
98
227
|
|
99
228
|
=begin rdoc
|
100
229
|
|
@@ -140,131 +269,63 @@ Queue
|
|
140
269
|
|
141
270
|
Bunny::Queue.new(self, name, opts)
|
142
271
|
end
|
143
|
-
|
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)
|
151
|
-
end
|
152
|
-
|
153
|
-
def send_frame(*args)
|
154
|
-
args.each do |data|
|
155
|
-
data.ticket = ticket if ticket and data.respond_to?(:ticket=)
|
156
|
-
data = data.to_frame(channel.number) unless data.is_a?(Qrack::Transport::Frame)
|
157
|
-
data.channel = channel.number
|
158
|
-
|
159
|
-
@logger.info("send") { data } if @logging
|
160
|
-
write(data.to_s)
|
161
|
-
end
|
162
|
-
|
163
|
-
nil
|
164
|
-
end
|
165
|
-
|
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
|
187
|
-
end
|
188
|
-
|
189
|
-
def next_payload
|
190
|
-
frame = next_frame
|
191
|
-
frame.payload
|
192
|
-
end
|
193
|
-
|
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
|
232
272
|
|
233
273
|
=begin rdoc
|
234
274
|
|
235
275
|
=== DESCRIPTION:
|
236
276
|
|
237
|
-
|
238
|
-
|
277
|
+
Asks the broker to redeliver all unacknowledged messages on a specified channel. Zero or
|
278
|
+
more messages may be redelivered.
|
239
279
|
|
240
|
-
====
|
280
|
+
==== Options:
|
241
281
|
|
242
|
-
<tt>:
|
282
|
+
* <tt>:requeue => true or false (_default_)</tt> - If set to _false_, the message will be
|
283
|
+
redelivered to the original recipient. If set to _true_, the server will attempt to requeue
|
284
|
+
the message, potentially then delivering it to an alternative subscriber.
|
243
285
|
|
244
286
|
=end
|
245
287
|
|
246
|
-
|
247
|
-
# Close all active channels
|
248
|
-
channels.each do |c|
|
249
|
-
c.close if c.open?
|
250
|
-
end
|
288
|
+
def recover(opts = {})
|
251
289
|
|
252
|
-
|
253
|
-
|
290
|
+
send_frame(
|
291
|
+
Qrack::Protocol::Basic::Recover.new({ :requeue => false }.merge(opts))
|
292
|
+
)
|
254
293
|
|
255
|
-
|
256
|
-
|
257
|
-
|
294
|
+
end
|
295
|
+
|
296
|
+
def request_access
|
297
|
+
send_frame(
|
298
|
+
Qrack::Protocol::Access::Request.new(:realm => '/data', :read => true, :write => true, :active => true, :passive => true)
|
299
|
+
)
|
300
|
+
method = next_method
|
301
|
+
raise Bunny::ProtocolError, 'Access denied' unless method.is_a?(Qrack::Protocol::Access::RequestOk)
|
302
|
+
self.ticket = method.ticket
|
303
|
+
end
|
304
|
+
|
305
|
+
def send_frame(*args)
|
306
|
+
args.each do |data|
|
307
|
+
data.ticket = ticket if ticket and data.respond_to?(:ticket=)
|
308
|
+
data = data.to_frame(channel.number) unless data.is_a?(Qrack::Transport::Frame)
|
309
|
+
data.channel = channel.number
|
258
310
|
|
259
|
-
|
311
|
+
@logger.info("send") { data } if @logging
|
312
|
+
write(data.to_s)
|
260
313
|
|
261
|
-
|
262
|
-
|
263
|
-
|
314
|
+
# Monitor client activity for heartbeat purposes
|
315
|
+
@message_out = true
|
316
|
+
end
|
264
317
|
|
265
|
-
|
266
|
-
send_command(:write, *args)
|
318
|
+
nil
|
267
319
|
end
|
320
|
+
|
321
|
+
def send_heartbeat
|
322
|
+
# Create a new heartbeat frame
|
323
|
+
hb = Qrack::Transport::Heartbeat.new('')
|
324
|
+
# Channel 0 must be used
|
325
|
+
switch_channel(0) if @channel.number > 0
|
326
|
+
# Send the heartbeat to server
|
327
|
+
send_frame(hb)
|
328
|
+
end
|
268
329
|
|
269
330
|
=begin rdoc
|
270
331
|
|
@@ -310,101 +371,20 @@ _Bunny_::_ProtocolError_ is raised. If successful, _Client_._status_ is set to <
|
|
310
371
|
|
311
372
|
=begin rdoc
|
312
373
|
|
313
|
-
=== DESCRIPTION:
|
314
|
-
|
315
|
-
Asks the broker to redeliver all unacknowledged messages on a specified channel. Zero or
|
316
|
-
more messages may be redelivered.
|
317
|
-
|
318
|
-
==== Options:
|
319
|
-
|
320
|
-
* <tt>:requeue => true or false (_default_)</tt> - If set to _false_, the message will be
|
321
|
-
redelivered to the original recipient. If set to _true_, the server will attempt to requeue
|
322
|
-
the message, potentially then delivering it to an alternative subscriber.
|
323
|
-
|
324
|
-
=end
|
325
|
-
|
326
|
-
def recover(opts = {})
|
327
|
-
|
328
|
-
send_frame(
|
329
|
-
Qrack::Protocol::Basic::Recover.new({ :requeue => false }.merge(opts))
|
330
|
-
)
|
331
|
-
|
332
|
-
end
|
333
|
-
|
334
|
-
=begin rdoc
|
335
|
-
|
336
|
-
=== DESCRIPTION:
|
337
|
-
|
338
|
-
Requests a specific quality of service. The QoS can be specified for the current channel
|
339
|
-
or for all channels on the connection. The particular properties and semantics of a QoS
|
340
|
-
method always depend on the content class semantics. Though the QoS method could in principle
|
341
|
-
apply to both peers, it is currently meaningful only for the server.
|
342
|
-
|
343
|
-
==== Options:
|
344
|
-
|
345
|
-
* <tt>:prefetch_size => size in no. of octets (default = 0)</tt> - The client can request that
|
346
|
-
messages be sent in advance so that when the client finishes processing a message, the following
|
347
|
-
message is already held locally, rather than needing to be sent down the channel. Prefetching gives
|
348
|
-
a performance improvement. This field specifies the prefetch window size in octets. The server
|
349
|
-
will send a message in advance if it is equal to or smaller in size than the available prefetch
|
350
|
-
size (and also falls into other prefetch limits). May be set to zero, meaning "no specific limit",
|
351
|
-
although other prefetch limits may still apply. The prefetch-size is ignored if the no-ack option
|
352
|
-
is set.
|
353
|
-
* <tt>:prefetch_count => no. messages (default = 1)</tt> - Specifies a prefetch window in terms
|
354
|
-
of whole messages. This field may be used in combination with the prefetch-size field; a message
|
355
|
-
will only be sent in advance if both prefetch windows (and those at the channel and connection level)
|
356
|
-
allow it. The prefetch-count is ignored if the no-ack option is set.
|
357
|
-
* <tt>:global => true or false (_default_)</tt> - By default the QoS settings apply to the current channel only. If set to
|
358
|
-
true, they are applied to the entire connection.
|
359
|
-
|
360
|
-
=end
|
361
|
-
|
362
|
-
def qos(opts = {})
|
363
|
-
|
364
|
-
send_frame(
|
365
|
-
Qrack::Protocol::Basic::Qos.new({ :prefetch_size => 0, :prefetch_count => 1, :global => false }.merge(opts))
|
366
|
-
)
|
367
|
-
|
368
|
-
raise Bunny::ProtocolError,
|
369
|
-
"Error specifying Quality of Service" unless
|
370
|
-
next_method.is_a?(Qrack::Protocol::Basic::QosOk)
|
371
|
-
|
372
|
-
# return confirmation
|
373
|
-
:qos_ok
|
374
|
-
end
|
375
|
-
|
376
|
-
=begin rdoc
|
377
|
-
|
378
|
-
=== DESCRIPTION:
|
379
|
-
This method sets the channel to use standard transactions. The
|
380
|
-
client must use this method at least once on a channel before
|
381
|
-
using the Commit or Rollback methods.
|
382
|
-
|
383
|
-
=end
|
384
|
-
|
385
|
-
def tx_select
|
386
|
-
send_frame(Qrack::Protocol::Tx::Select.new())
|
387
|
-
|
388
|
-
raise Bunny::ProtocolError,
|
389
|
-
"Error initiating transactions for current channel" unless
|
390
|
-
next_method.is_a?(Qrack::Protocol::Tx::SelectOk)
|
391
|
-
|
392
|
-
# return confirmation
|
393
|
-
:select_ok
|
394
|
-
end
|
395
|
-
|
396
|
-
=begin rdoc
|
397
|
-
|
398
374
|
=== DESCRIPTION:
|
399
375
|
This method commits all messages published and acknowledged in
|
400
376
|
the current transaction. A new transaction starts immediately
|
401
377
|
after a commit.
|
402
378
|
|
379
|
+
==== RETURNS:
|
380
|
+
|
381
|
+
<tt>:commit_ok</tt> if successful.
|
382
|
+
|
403
383
|
=end
|
404
|
-
|
384
|
+
|
405
385
|
def tx_commit
|
406
386
|
send_frame(Qrack::Protocol::Tx::Commit.new())
|
407
|
-
|
387
|
+
|
408
388
|
raise Bunny::ProtocolError,
|
409
389
|
"Error commiting transaction" unless
|
410
390
|
next_method.is_a?(Qrack::Protocol::Tx::CommitOk)
|
@@ -420,11 +400,15 @@ This method abandons all messages published and acknowledged in
|
|
420
400
|
the current transaction. A new transaction starts immediately
|
421
401
|
after a rollback.
|
422
402
|
|
403
|
+
==== RETURNS:
|
404
|
+
|
405
|
+
<tt>:rollback_ok</tt> if successful.
|
406
|
+
|
423
407
|
=end
|
424
|
-
|
408
|
+
|
425
409
|
def tx_rollback
|
426
410
|
send_frame(Qrack::Protocol::Tx::Rollback.new())
|
427
|
-
|
411
|
+
|
428
412
|
raise Bunny::ProtocolError,
|
429
413
|
"Error rolling back transaction" unless
|
430
414
|
next_method.is_a?(Qrack::Protocol::Tx::RollbackOk)
|
@@ -432,98 +416,29 @@ after a rollback.
|
|
432
416
|
# return confirmation
|
433
417
|
:rollback_ok
|
434
418
|
end
|
435
|
-
|
436
|
-
def logging=(bool)
|
437
|
-
@logging = bool
|
438
|
-
create_logger if @logging
|
439
|
-
end
|
440
|
-
|
441
|
-
def create_channel
|
442
|
-
channels.each do |c|
|
443
|
-
return c if (!c.open? and c.number != 0)
|
444
|
-
end
|
445
|
-
# If no channel to re-use instantiate new one
|
446
|
-
Bunny::Channel.new(self)
|
447
|
-
end
|
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
|
-
|
462
|
-
def init_connection
|
463
|
-
write(Qrack::Protocol::HEADER)
|
464
|
-
write([1, 1, Qrack::Protocol::VERSION_MAJOR, Qrack::Protocol::VERSION_MINOR].pack('C4'))
|
465
419
|
|
466
|
-
|
467
|
-
if frame.nil? or !frame.payload.is_a?(Qrack::Protocol::Connection::Start)
|
468
|
-
raise Bunny::ProtocolError, 'Connection initiation failed'
|
469
|
-
end
|
470
|
-
end
|
471
|
-
|
472
|
-
def open_connection
|
473
|
-
send_frame(
|
474
|
-
Qrack::Protocol::Connection::StartOk.new(
|
475
|
-
{:platform => 'Ruby', :product => 'Bunny', :information => 'http://github.com/celldee/bunny', :version => VERSION},
|
476
|
-
'AMQPLAIN',
|
477
|
-
{:LOGIN => @user, :PASSWORD => @pass},
|
478
|
-
'en_US'
|
479
|
-
)
|
480
|
-
)
|
420
|
+
=begin rdoc
|
481
421
|
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
422
|
+
=== DESCRIPTION:
|
423
|
+
This method sets the channel to use standard transactions. The
|
424
|
+
client must use this method at least once on a channel before
|
425
|
+
using the Commit or Rollback methods.
|
486
426
|
|
487
|
-
|
488
|
-
send_frame(
|
489
|
-
Qrack::Protocol::Connection::TuneOk.new( :channel_max => @channel_max, :frame_max => @frame_max, :heartbeat => @heartbeat)
|
490
|
-
)
|
491
|
-
end
|
427
|
+
==== RETURNS:
|
492
428
|
|
493
|
-
|
494
|
-
Qrack::Protocol::Connection::Open.new(:virtual_host => @vhost, :capabilities => '', :insist => @insist)
|
495
|
-
)
|
429
|
+
<tt>:select_ok</tt> if successful.
|
496
430
|
|
497
|
-
|
498
|
-
when Qrack::Protocol::Connection::OpenOk
|
499
|
-
return :ok
|
500
|
-
when Qrack::Protocol::Connection::Redirect
|
501
|
-
raise Bunny::ConnectionError, "Cannot connect to the specified server - host: #{@host}, port: #{@port}" if @insist
|
502
|
-
|
503
|
-
@host, @port = method.host.split(':')
|
504
|
-
close_socket
|
505
|
-
else
|
506
|
-
raise Bunny::ProtocolError, 'Cannot open connection'
|
507
|
-
end
|
508
|
-
end
|
431
|
+
=end
|
509
432
|
|
510
|
-
def
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
)
|
517
|
-
raise Bunny::ProtocolError, "Error closing connection" unless next_method.is_a?(Qrack::Protocol::Connection::CloseOk)
|
518
|
-
end
|
433
|
+
def tx_select
|
434
|
+
send_frame(Qrack::Protocol::Tx::Select.new())
|
435
|
+
|
436
|
+
raise Bunny::ProtocolError,
|
437
|
+
"Error initiating transactions for current channel" unless
|
438
|
+
next_method.is_a?(Qrack::Protocol::Tx::SelectOk)
|
519
439
|
|
520
|
-
|
521
|
-
|
522
|
-
Qrack::Protocol::Access::Request.new(:realm => '/data', :read => true, :write => true, :active => true, :passive => true)
|
523
|
-
)
|
524
|
-
method = next_method
|
525
|
-
raise Bunny::ProtocolError, 'Access denied' unless method.is_a?(Qrack::Protocol::Access::RequestOk)
|
526
|
-
self.ticket = method.ticket
|
440
|
+
# return confirmation
|
441
|
+
:select_ok
|
527
442
|
end
|
528
443
|
|
529
444
|
private
|
@@ -532,47 +447,5 @@ after a rollback.
|
|
532
447
|
@buffer ||= Qrack::Transport::Buffer.new(self)
|
533
448
|
end
|
534
449
|
|
535
|
-
def send_command(cmd, *args)
|
536
|
-
begin
|
537
|
-
raise Bunny::ConnectionError, 'No connection - socket has not been created' if !@socket
|
538
|
-
@socket.__send__(cmd, *args)
|
539
|
-
rescue Errno::EPIPE, IOError => e
|
540
|
-
raise Bunny::ServerDownError, e.message
|
541
|
-
end
|
542
|
-
end
|
543
|
-
|
544
|
-
def socket
|
545
|
-
return @socket if @socket and (@status == :connected) and not @socket.closed?
|
546
|
-
|
547
|
-
begin
|
548
|
-
# Attempt to connect.
|
549
|
-
@socket = timeout(CONNECT_TIMEOUT) do
|
550
|
-
TCPSocket.new(host, port)
|
551
|
-
end
|
552
|
-
|
553
|
-
if Socket.constants.include? 'TCP_NODELAY'
|
554
|
-
@socket.setsockopt Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1
|
555
|
-
end
|
556
|
-
rescue => e
|
557
|
-
@status = :not_connected
|
558
|
-
raise Bunny::ServerDownError, e.message
|
559
|
-
end
|
560
|
-
|
561
|
-
@socket
|
562
|
-
end
|
563
|
-
|
564
|
-
def close_socket(reason=nil)
|
565
|
-
# Close the socket. The server is not considered dead.
|
566
|
-
@socket.close if @socket and not @socket.closed?
|
567
|
-
@socket = nil
|
568
|
-
@status = :not_connected
|
569
|
-
end
|
570
|
-
|
571
|
-
def create_logger
|
572
|
-
@logfile ? @logger = Logger.new("#{logfile}") : @logger = Logger.new(STDOUT)
|
573
|
-
@logger.level = Logger::INFO
|
574
|
-
@logger.datetime_format = "%Y-%m-%d %H:%M:%S"
|
575
|
-
end
|
576
|
-
|
577
450
|
end
|
578
451
|
end
|