bunny 0.9.0.rc1 → 0.9.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/ChangeLog.md +95 -2
- data/README.md +81 -26
- data/bunny.gemspec +2 -2
- data/lib/bunny/channel.rb +7 -3
- data/lib/bunny/consumer_work_pool.rb +11 -3
- data/lib/bunny/queue.rb +0 -48
- data/lib/bunny/session.rb +3 -8
- data/lib/bunny/transport.rb +37 -11
- data/lib/bunny/version.rb +1 -1
- data/spec/higher_level_api/integration/basic_consume_spec.rb +50 -1
- data/spec/higher_level_api/integration/basic_get_spec.rb +2 -36
- data/spec/higher_level_api/integration/connection_spec.rb +33 -24
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 23f16e1a514fe184d1460364e3a04247ddedf75d
|
4
|
+
data.tar.gz: a9e0dbba16677d8671a2e20ead8a0b5aa120b9ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ede8a080ddae75c6011790a72fa0cb1d21e13e227cba2e4ab3fc35fc5e8b99649601595061ae4f178b3c965487f91ba75944a22fdf86bc51d144e2cf61ca8839
|
7
|
+
data.tar.gz: 7988d768033079976e984ec930684d195df9ee7dd54e83520149134eed080cec31cbecf83ed4f906e1bcdfbc14b7b90d22445cd0a697826d8b031fe3200d560c
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0@
|
1
|
+
2.0@rabbitmq
|
data/ChangeLog.md
CHANGED
@@ -1,7 +1,93 @@
|
|
1
|
-
## Changes between Bunny 0.9.0.
|
1
|
+
## Changes between Bunny 0.9.0.rc1 and 0.9.0.rc2
|
2
|
+
|
3
|
+
### Channel Now Properly Restarts Consumer Pool
|
4
|
+
|
5
|
+
In a case when all consumers are cancelled, `Bunny::Channel`
|
6
|
+
will shut down its consumer delivery thread pool.
|
7
|
+
|
8
|
+
It will also now mark the pool as not running so that it can be
|
9
|
+
started again successfully if new consumers are registered later.
|
10
|
+
|
11
|
+
GH issue: #133.
|
12
|
+
|
13
|
+
|
14
|
+
### Bunny::Queue#pop_waiting is Removed
|
15
|
+
|
16
|
+
A little bit of background: on MRI, the method raised `ThreadErrors`
|
17
|
+
reliably. On JRuby, we used a different [internal] queue implementation
|
18
|
+
from JDK so it wasn't an issue.
|
19
|
+
|
20
|
+
`Timeout.timeout` uses `Thread#kill` and `Thread#join`, both of which
|
21
|
+
eventually attempt to acquire a mutex used by Queue#pop, which Bunny
|
22
|
+
currently uses for continuations. The mutex is already has an owner
|
23
|
+
and so a ThreadError is raised.
|
24
|
+
|
25
|
+
This is not a problem on JRuby because there we don't use Ruby's
|
26
|
+
Timeout and Queue and instead rely on a JDK concurrency primitive
|
27
|
+
which provides "poll with a timeout".
|
28
|
+
|
29
|
+
[The issue with `Thread#kill` and `Thread#raise`](http://blog.headius.com/2008/02/ruby-threadraise-threadkill-timeoutrb.html)
|
30
|
+
has been first investigated and blogged about by Ruby implementers
|
31
|
+
in 2008.
|
32
|
+
|
33
|
+
Finding a workaround will probably take a bit of time and may involve
|
34
|
+
reimplementing standard library and core classes.
|
35
|
+
|
36
|
+
We don't want this issue to block Bunny 0.9 release. Neither we want
|
37
|
+
to ship a broken feature. So as a result, we will drop
|
38
|
+
Bunny::Queue#pop_waiting since it cannot be reliably implemented in a
|
39
|
+
reasonable amount of time on MRI.
|
40
|
+
|
41
|
+
Per issue #131.
|
42
|
+
|
43
|
+
|
44
|
+
### More Flexible SSLContext Configuration
|
45
|
+
|
46
|
+
Bunny will now upgrade connection to SSL in `Bunny::Session#start`,
|
47
|
+
so it is possible to fine tune SSLContext and socket settings
|
48
|
+
before that:
|
49
|
+
|
50
|
+
``` ruby
|
51
|
+
require "bunny"
|
52
|
+
|
53
|
+
conn = Bunny.new(:tls => true,
|
54
|
+
:tls_cert => "examples/tls/client_cert.pem",
|
55
|
+
:tls_key => "examples/tls/client_key.pem",
|
56
|
+
:tls_ca_certificates => ["./examples/tls/cacert.pem"])
|
57
|
+
|
58
|
+
puts conn.transport.socket.inspect
|
59
|
+
puts conn.transport.tls_context.inspect
|
60
|
+
```
|
61
|
+
|
62
|
+
This also means that `Bunny.new` will now open the socket. Previously
|
63
|
+
it was only done when `Bunny::Session#start` was invoked.
|
64
|
+
|
65
|
+
|
66
|
+
## Changes between Bunny 0.9.0.pre13 and 0.9.0.rc1
|
67
|
+
|
68
|
+
### TLS Support
|
69
|
+
|
70
|
+
Bunny 0.9 finally supports TLS. There are 3 new options `Bunny.new` takes:
|
71
|
+
|
72
|
+
* `:tls` which, when set to `true`, will set SSL context up and switch to TLS port (5671)
|
73
|
+
* `:tls_cert` which is a string path to the client certificate (public key) in PEM format
|
74
|
+
* `:tls_key` which is a string path to the client key (private key) in PEM format
|
75
|
+
* `:tls_ca_certificates` which is an array of string paths to CA certificates in PEM format
|
76
|
+
|
77
|
+
An example:
|
78
|
+
|
79
|
+
``` ruby
|
80
|
+
conn = Bunny.new(:tls => true,
|
81
|
+
:tls_cert => "examples/tls/client_cert.pem",
|
82
|
+
:tls_key => "examples/tls/client_key.pem",
|
83
|
+
:tls_ca_certificates => ["./examples/tls/cacert.pem"])
|
84
|
+
```
|
85
|
+
|
2
86
|
|
3
87
|
### Bunny::Queue#pop_waiting
|
4
88
|
|
89
|
+
**This function was removed in v0.9.0.rc2**
|
90
|
+
|
5
91
|
`Bunny::Queue#pop_waiting` is a new function that mimics `Bunny::Queue#pop`
|
6
92
|
but will wait until a message is available. It uses a `:timeout` option and will
|
7
93
|
raise an exception if the timeout is hit:
|
@@ -20,6 +106,13 @@ q.pop_waiting(:timeout => 0.5)
|
|
20
106
|
This method only makes sense for collecting Request/Reply ("RPC") replies.
|
21
107
|
|
22
108
|
|
109
|
+
### Bunny::InvalidCommand is now Bunny::CommandInvalid
|
110
|
+
|
111
|
+
`Bunny::InvalidCommand` is now `Bunny::CommandInvalid` (follows
|
112
|
+
the exception class naming convention based on response status
|
113
|
+
name).
|
114
|
+
|
115
|
+
|
23
116
|
|
24
117
|
## Changes between Bunny 0.9.0.pre12 and 0.9.0.pre13
|
25
118
|
|
@@ -533,7 +626,7 @@ It makes more sense for beginners that way.
|
|
533
626
|
|
534
627
|
`Bunny::Queue#subscribe` support the new `:block` option
|
535
628
|
(a boolean).
|
536
|
-
|
629
|
+
|
537
630
|
It controls whether the current thread will be blocked
|
538
631
|
by `Bunny::Queue#subscribe`.
|
539
632
|
|
data/README.md
CHANGED
@@ -1,13 +1,56 @@
|
|
1
1
|
# Bunny, a Ruby RabbitMQ Client
|
2
2
|
|
3
|
-
Bunny is a synchronous RabbitMQ client that focuses on ease of use.
|
4
|
-
|
5
|
-
|
3
|
+
Bunny is a synchronous RabbitMQ client that focuses on ease of use. It
|
4
|
+
is feature complete, supports all RabbitMQ 3.0 features and does not
|
5
|
+
have any heavyweight dependencies.
|
6
|
+
|
7
|
+
|
8
|
+
## I Know What RabbitMQ and Bunny are, How Do I Get Started?
|
9
|
+
|
10
|
+
[Right here](http://rubybunny.info/articles/getting_started.html)!
|
11
|
+
|
12
|
+
|
13
|
+
## What is Bunny Good For?
|
14
|
+
|
15
|
+
One can use amqp gem to make Ruby applications interoperate with other
|
16
|
+
applications (both Ruby and not). Complexity and size may vary from
|
17
|
+
simple work queues to complex multi-stage data processing workflows that involve
|
18
|
+
many applications built with all kinds of technologies.
|
19
|
+
|
20
|
+
Specific examples:
|
21
|
+
|
22
|
+
* Events collectors, metrics & analytics applications can aggregate events produced by various applications
|
23
|
+
(Web and not) in the company network.
|
24
|
+
|
25
|
+
* A Web application may route messages to a Java app that works
|
26
|
+
with SMS delivery gateways.
|
27
|
+
|
28
|
+
* MMO games can use flexible routing RabbitMQ provides to propagate event notifications to players and locations.
|
29
|
+
|
30
|
+
* Price updates from public markets or other sources can be distributed between interested parties, from trading systems to points of sale in a specific geographic region.
|
31
|
+
|
32
|
+
* Content aggregators may update full-text search and geospatial search indexes
|
33
|
+
by delegating actual indexing work to other applications over RabbitMQ.
|
34
|
+
|
35
|
+
* Companies may provide streaming/push APIs to their customers, partners
|
36
|
+
or just general public.
|
37
|
+
|
38
|
+
* Continuous integration systems can distribute builds between multiple machines with various hardware and software
|
39
|
+
configurations using advanced routing features of RabbitMQ.
|
40
|
+
|
41
|
+
* An application that watches updates from a real-time stream (be it markets data
|
42
|
+
or Twitter stream) can propagate updates to interested parties, including
|
43
|
+
Web applications that display that information in the real time.
|
44
|
+
|
6
45
|
|
7
46
|
|
8
47
|
## Supported Ruby Versions
|
9
48
|
|
10
|
-
Bunny 0.9 and more recent versions support
|
49
|
+
Bunny 0.9 and more recent versions support
|
50
|
+
|
51
|
+
* CRuby 1.9.3, 1.9.2, 2.0.0, and 1.8.7
|
52
|
+
* JRuby 1.7+
|
53
|
+
* Rubinius 2.0+
|
11
54
|
|
12
55
|
|
13
56
|
## Supported RabbitMQ Versions
|
@@ -16,13 +59,20 @@ Bunny `0.8.x` and later versions only support RabbitMQ 2.x and 3.x.
|
|
16
59
|
Bunny `0.7.x` and earlier versions support RabbitMQ 1.x and 2.x.
|
17
60
|
|
18
61
|
|
19
|
-
##
|
62
|
+
## Project Maturity
|
20
63
|
|
21
|
-
Bunny is a
|
22
|
-
|
23
|
-
|
64
|
+
Bunny is a pretty old (started circa late 2008) library that, before version 0.9, **a lot** of missing functionality. Version 0.9
|
65
|
+
can be considered to be "second birthday" for Bunny as it was rewritten from scratch. Key objectives
|
66
|
+
for 0.9 are
|
24
67
|
|
25
|
-
|
68
|
+
* Be feature complete, support all RabbitMQ 3.x features
|
69
|
+
* Eliminate limitations Bunny used to have with earlier versions
|
70
|
+
* Be [well documented](http://rubybunny.info)
|
71
|
+
* Make use of concurrency and, if the runtime provides it, parallelism
|
72
|
+
* Reuse code with amqp gem and possibly other clients where it makes sense
|
73
|
+
|
74
|
+
We (the maintainers) make our best to keep the new version as
|
75
|
+
backwards compatible as possible but within reason.
|
26
76
|
|
27
77
|
|
28
78
|
## Installation & Bundler Dependency
|
@@ -33,12 +83,12 @@ To install Bunny 0.9.x with RubyGems:
|
|
33
83
|
gem install bunny --pre
|
34
84
|
```
|
35
85
|
|
36
|
-
the most recent 0.9.x version is `0.9.0.
|
86
|
+
the most recent 0.9.x version is `0.9.0.rc1`.
|
37
87
|
|
38
88
|
To use Bunny 0.9.x in a project managed with Bundler:
|
39
89
|
|
40
90
|
``` ruby
|
41
|
-
gem "bunny", ">= 0.9.0.
|
91
|
+
gem "bunny", ">= 0.9.0.rc1" # optionally: , :git => "git://github.com/ruby-amqp/bunny.git", :branch => "master"
|
42
92
|
```
|
43
93
|
|
44
94
|
|
@@ -62,11 +112,8 @@ ch = conn.create_channel
|
|
62
112
|
# declare a queue
|
63
113
|
q = ch.queue("test1")
|
64
114
|
|
65
|
-
# default
|
66
|
-
|
67
|
-
|
68
|
-
# publish a message to the exchange which then gets routed to the queue
|
69
|
-
e.publish("Hello, everybody!", :routing_key => 'test1')
|
115
|
+
# publish a message to the default exchange which then gets routed to this queue
|
116
|
+
q.publish("Hello, everybody!")
|
70
117
|
|
71
118
|
# fetch a message from the queue
|
72
119
|
delivery_info, metadata, payload = q.pop
|
@@ -86,7 +133,17 @@ For a 15 minute tutorial using more practical examples, see [Getting Started wit
|
|
86
133
|
|
87
134
|
### Guides
|
88
135
|
|
89
|
-
Other documentation guides are available at [rubybunny.info](http://rubybunny.info)
|
136
|
+
Other documentation guides are available at [rubybunny.info](http://rubybunny.info):
|
137
|
+
|
138
|
+
* [Queues and Consumers](http://rubybunny.info/articles/queues.html)
|
139
|
+
* [Exchanges and Publishers](http://rubybunny.info/articles/exchanges.html)
|
140
|
+
* [AMQP 0.9.1 Model Explained](http://www.rabbitmq.com/tutorials/amqp-concepts.html)
|
141
|
+
* [Connecting to RabbitMQ](http://rubybunny.info/articles/connecting.html)
|
142
|
+
* [Error Handling and Recovery](http://rubybunny.info/articles/error_handling.html)
|
143
|
+
* [TLS/SSL Support](http://rubybunny.info/articles/tls.html)
|
144
|
+
* [Bindings](http://rubybunny.info/articles/bindings.html)
|
145
|
+
* [Using RabbitMQ Extensions with Bunny](http://rubybunny.info/articles/extensions.html)
|
146
|
+
* [Durability and Related Matters](http://rubybunny.info/articles/durability.html)
|
90
147
|
|
91
148
|
### API Reference
|
92
149
|
|
@@ -110,6 +167,11 @@ For more immediate help, please join `#rabbitmq` on `irc.freenode.net`.
|
|
110
167
|
|
111
168
|
To subscribe for announcements of releases, important changes and so on, please follow [@rubyamqp](https://twitter.com/#!/rubyamqp) on Twitter.
|
112
169
|
|
170
|
+
More detailed announcements can be found in the blogs
|
171
|
+
|
172
|
+
* [RabbitMQ Ruby clients blog](http://blog.rubyrabbitmq.info)
|
173
|
+
* [Bunny Blog](http://bunnyamqp.wordpress.com)
|
174
|
+
|
113
175
|
|
114
176
|
### Reporting Issues
|
115
177
|
|
@@ -144,13 +206,6 @@ After that create a branch and make your changes on it. Once you are done with y
|
|
144
206
|
on GitHub.
|
145
207
|
|
146
208
|
|
209
|
+
## License
|
147
210
|
|
148
|
-
|
149
|
-
|
150
|
-
* [AMQP 0.9.1 model explained](http://www.rabbitmq.com/tutorials/amqp-concepts.html): introductory explanation of the AMQP v0.9.1 specification with particular reference to RabbitMQ.
|
151
|
-
|
152
|
-
|
153
|
-
## Links
|
154
|
-
|
155
|
-
* [Source code](http://github.com/ruby-amqp/bunny)
|
156
|
-
* [Blog](http://bunnyamqp.wordpress.com)
|
211
|
+
Released under the MIT license.
|
data/bunny.gemspec
CHANGED
@@ -7,9 +7,9 @@ require File.expand_path("../lib/bunny/version", __FILE__)
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "bunny"
|
9
9
|
s.version = Bunny::VERSION.dup
|
10
|
-
s.homepage = "http://
|
10
|
+
s.homepage = "http://rubybunny.info"
|
11
11
|
s.summary = "Popular easy to use Ruby client for RabbitMQ"
|
12
|
-
s.description = "
|
12
|
+
s.description = "Easy to use, feature complete Ruby client for RabbitMQ 2.0."
|
13
13
|
s.license = "MIT"
|
14
14
|
|
15
15
|
# Sorted alphabetically.
|
data/lib/bunny/channel.rb
CHANGED
@@ -1690,17 +1690,21 @@ module Bunny
|
|
1690
1690
|
# publishing). MK.
|
1691
1691
|
# @private
|
1692
1692
|
def maybe_start_consumer_work_pool!
|
1693
|
-
@work_pool
|
1693
|
+
if @work_pool && !@work_pool.running?
|
1694
|
+
@work_pool.start
|
1695
|
+
end
|
1694
1696
|
end
|
1695
1697
|
|
1696
1698
|
# @private
|
1697
1699
|
def maybe_pause_consumer_work_pool!
|
1698
|
-
@work_pool.pause if @work_pool && @work_pool.
|
1700
|
+
@work_pool.pause if @work_pool && @work_pool.running?
|
1699
1701
|
end
|
1700
1702
|
|
1701
1703
|
# @private
|
1702
1704
|
def maybe_kill_consumer_work_pool!
|
1703
|
-
|
1705
|
+
if @work_pool && @work_pool.running?
|
1706
|
+
@work_pool.kill
|
1707
|
+
end
|
1704
1708
|
end
|
1705
1709
|
|
1706
1710
|
# @private
|
@@ -31,14 +31,16 @@ module Bunny
|
|
31
31
|
@threads << t
|
32
32
|
end
|
33
33
|
|
34
|
-
@
|
34
|
+
@running = true
|
35
35
|
end
|
36
36
|
|
37
|
-
def
|
38
|
-
@
|
37
|
+
def running?
|
38
|
+
@running
|
39
39
|
end
|
40
40
|
|
41
41
|
def shutdown
|
42
|
+
@running = false
|
43
|
+
|
42
44
|
@size.times do
|
43
45
|
submit do |*args|
|
44
46
|
throw :terminate
|
@@ -51,14 +53,20 @@ module Bunny
|
|
51
53
|
end
|
52
54
|
|
53
55
|
def pause
|
56
|
+
@running = false
|
57
|
+
|
54
58
|
@threads.each { |t| t.stop }
|
55
59
|
end
|
56
60
|
|
57
61
|
def resume
|
62
|
+
@running = true
|
63
|
+
|
58
64
|
@threads.each { |t| t.run }
|
59
65
|
end
|
60
66
|
|
61
67
|
def kill
|
68
|
+
@running = false
|
69
|
+
|
62
70
|
@threads.each { |t| t.kill }
|
63
71
|
end
|
64
72
|
|
data/lib/bunny/queue.rb
CHANGED
@@ -256,54 +256,6 @@ module Bunny
|
|
256
256
|
end
|
257
257
|
end
|
258
258
|
|
259
|
-
# @param [Hash] opts Options
|
260
|
-
#
|
261
|
-
# @option opts [Boolean] :ack (false) Will the message be acknowledged manually?
|
262
|
-
# @option opts [Float] :timeout (1.0) Max amount of time, in seconds, to wait before raising an exception
|
263
|
-
#
|
264
|
-
# @return [Array] Triple of delivery info, message properties and message content.
|
265
|
-
# If the queue is empty, all three will be nils.
|
266
|
-
#
|
267
|
-
# @raises [Bunny::ClientException] When no message is available in the amount of time provided via the :timeout option
|
268
|
-
#
|
269
|
-
# @see http://rubybunny.info/articles/queues.html Queues and Consumers guide
|
270
|
-
# @see Bunny::Queue#subscribe
|
271
|
-
# @api public
|
272
|
-
#
|
273
|
-
# @example
|
274
|
-
# conn = Bunny.new
|
275
|
-
# conn.start
|
276
|
-
#
|
277
|
-
# ch = conn.create_channel
|
278
|
-
# q = ch.queue("test1")
|
279
|
-
# x = ch.default_exchange
|
280
|
-
# x.publish("Hello, everybody!", :routing_key => 'test1')
|
281
|
-
#
|
282
|
-
# delivery_info, properties, payload = q.pop_waiting(:timeout => 0.5)
|
283
|
-
#
|
284
|
-
# puts "This is the message: " + payload + "\n\n"
|
285
|
-
# conn.close
|
286
|
-
def pop_waiting(opts = {:ack => false, :timeout => 1.0}, &block)
|
287
|
-
delivery_info, properties, content = nil, nil, nil
|
288
|
-
|
289
|
-
Bunny::Timer.timeout(opts[:timeout], ClientTimeout) do
|
290
|
-
loop do
|
291
|
-
delivery_info, properties, content = @channel.basic_get(@name, opts)
|
292
|
-
|
293
|
-
if !content.nil?
|
294
|
-
break
|
295
|
-
end
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
if block
|
300
|
-
block.call(delivery_info, properties, content)
|
301
|
-
else
|
302
|
-
[delivery_info, properties, content]
|
303
|
-
end
|
304
|
-
end
|
305
|
-
alias get_waiting pop_waiting
|
306
|
-
|
307
259
|
|
308
260
|
# Publishes a message to the queue via default exchange. Takes the same arguments
|
309
261
|
# as {Bunny::Exchange#publish}
|
data/lib/bunny/session.rb
CHANGED
@@ -178,11 +178,7 @@ module Bunny
|
|
178
178
|
def configure_socket(&block)
|
179
179
|
raise ArgumentError, "No block provided!" if block.nil?
|
180
180
|
|
181
|
-
|
182
|
-
@transport.configure_socket(&block)
|
183
|
-
else
|
184
|
-
@socket_configurator = block
|
185
|
-
end
|
181
|
+
@transport.configure_socket(&block)
|
186
182
|
end
|
187
183
|
|
188
184
|
# Starts the connection process.
|
@@ -199,10 +195,9 @@ module Bunny
|
|
199
195
|
begin
|
200
196
|
# close existing transport if we have one,
|
201
197
|
# to not leak sockets
|
202
|
-
|
203
|
-
self.initialize_transport
|
198
|
+
@transport.maybe_initialize_socket
|
204
199
|
|
205
|
-
@transport.
|
200
|
+
@transport.post_initialize_socket
|
206
201
|
@transport.connect
|
207
202
|
|
208
203
|
if @socket_configurator
|
data/lib/bunny/transport.rb
CHANGED
@@ -49,6 +49,9 @@ module Bunny
|
|
49
49
|
@disconnect_timeout = @read_write_timeout || @connect_timeout
|
50
50
|
|
51
51
|
@writes_mutex = Mutex.new
|
52
|
+
|
53
|
+
maybe_initialize_socket
|
54
|
+
prepare_tls_context if @tls_enabled
|
52
55
|
end
|
53
56
|
|
54
57
|
|
@@ -71,15 +74,26 @@ module Bunny
|
|
71
74
|
if uses_ssl?
|
72
75
|
@socket.connect
|
73
76
|
@socket.post_connection_check(host) if uses_tls? && @verify_peer
|
77
|
+
|
78
|
+
@status = :connected
|
79
|
+
|
80
|
+
@socket
|
74
81
|
else
|
75
82
|
# no-op
|
76
83
|
end
|
77
84
|
end
|
78
85
|
|
86
|
+
def connected?
|
87
|
+
:not_connected == @status && open?
|
88
|
+
end
|
89
|
+
|
79
90
|
def configure_socket(&block)
|
80
|
-
block.call(@socket)
|
91
|
+
block.call(@socket) if @socket
|
81
92
|
end
|
82
93
|
|
94
|
+
def configure_tls_context(&block)
|
95
|
+
block.call(@tls_context) if @tls_context
|
96
|
+
end
|
83
97
|
|
84
98
|
# Writes data to the socket. If read/write timeout was specified, Bunny::ClientTimeout will be raised
|
85
99
|
# if the operation times out.
|
@@ -102,6 +116,7 @@ module Bunny
|
|
102
116
|
end
|
103
117
|
rescue SystemCallError, Bunny::ClientTimeout, Bunny::ConnectionError, IOError => e
|
104
118
|
close
|
119
|
+
@status = :not_connected
|
105
120
|
|
106
121
|
if @session.automatically_recover?
|
107
122
|
@session.handle_network_failure(e)
|
@@ -153,11 +168,11 @@ module Bunny
|
|
153
168
|
|
154
169
|
|
155
170
|
def close(reason = nil)
|
156
|
-
@socket.close if
|
171
|
+
@socket.close if open?
|
157
172
|
end
|
158
173
|
|
159
174
|
def open?
|
160
|
-
!@socket.closed?
|
175
|
+
@socket && !@socket.closed?
|
161
176
|
end
|
162
177
|
|
163
178
|
def closed?
|
@@ -224,17 +239,11 @@ module Bunny
|
|
224
239
|
|
225
240
|
def initialize_socket
|
226
241
|
begin
|
227
|
-
|
242
|
+
@socket = Bunny::Timer.timeout(@connect_timeout, ConnectionTimeout) do
|
228
243
|
Bunny::Socket.open(@host, @port,
|
229
244
|
:keepalive => @opts[:keepalive],
|
230
245
|
:socket_timeout => @connect_timeout)
|
231
246
|
end
|
232
|
-
|
233
|
-
@socket = if uses_tls?
|
234
|
-
wrap_in_tls_socket(s)
|
235
|
-
else
|
236
|
-
s
|
237
|
-
end
|
238
247
|
rescue StandardError, ConnectionTimeout => e
|
239
248
|
@status = :not_connected
|
240
249
|
raise Bunny::TCPConnectionFailed.new(e, self.hostname, self.port)
|
@@ -243,6 +252,18 @@ module Bunny
|
|
243
252
|
@socket
|
244
253
|
end
|
245
254
|
|
255
|
+
def maybe_initialize_socket
|
256
|
+
initialize_socket if !@socket || closed?
|
257
|
+
end
|
258
|
+
|
259
|
+
def post_initialize_socket
|
260
|
+
@socket = if uses_tls?
|
261
|
+
wrap_in_tls_socket(@socket)
|
262
|
+
else
|
263
|
+
@socket
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
246
267
|
protected
|
247
268
|
|
248
269
|
def tls_enabled?(opts)
|
@@ -257,10 +278,15 @@ module Bunny
|
|
257
278
|
opts[:tls_key] || opts[:ssl_key] || opts[:tls_key_path] || opts[:ssl_key_path]
|
258
279
|
end
|
259
280
|
|
260
|
-
def
|
281
|
+
def prepare_tls_context
|
261
282
|
read_tls_keys!
|
262
283
|
|
263
284
|
@tls_context = initialize_tls_context(OpenSSL::SSL::SSLContext.new)
|
285
|
+
end
|
286
|
+
|
287
|
+
def wrap_in_tls_socket(socket)
|
288
|
+
raise ArgumentError, "cannot wrap nil into TLS socket, @tls_context is nil. This is a Bunny bug." unless socket
|
289
|
+
raise "cannot wrap a socket into TLS socket, @tls_context is nil. This is a Bunny bug." unless @tls_context
|
264
290
|
|
265
291
|
s = Bunny::SSLSocket.new(socket, @tls_context)
|
266
292
|
s.sync_close = true
|
data/lib/bunny/version.rb
CHANGED
@@ -114,5 +114,54 @@ describe Bunny::Queue, "#subscribe" do
|
|
114
114
|
ch.close
|
115
115
|
end
|
116
116
|
end
|
117
|
+
end # 20.times
|
118
|
+
|
119
|
+
|
120
|
+
context "after consumer pool has already been shut down" do
|
121
|
+
let(:queue_name) { "bunny.basic_consume#{rand}" }
|
122
|
+
|
123
|
+
it "registers the consumer" do
|
124
|
+
delivered_keys = []
|
125
|
+
delivered_data = []
|
126
|
+
|
127
|
+
t = Thread.new do
|
128
|
+
ch = connection.create_channel
|
129
|
+
q = ch.queue(queue_name)
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
c1 = q.subscribe(:exclusive => false, :manual_ack => false, :block => false) do |delivery_info, properties, payload|
|
134
|
+
end
|
135
|
+
c1.cancel
|
136
|
+
puts "Cancelled #{c1.consumer_tag}"
|
137
|
+
|
138
|
+
c2 = q.subscribe(:exclusive => false, :manual_ack => false, :block => false) do |delivery_info, properties, payload|
|
139
|
+
delivered_keys << delivery_info.routing_key
|
140
|
+
delivered_data << payload
|
141
|
+
end
|
142
|
+
c2.cancel
|
143
|
+
puts "Cancelled #{c2.consumer_tag}"
|
144
|
+
|
145
|
+
q.subscribe(:exclusive => false, :manual_ack => false, :block => true) do |delivery_info, properties, payload|
|
146
|
+
delivered_keys << delivery_info.routing_key
|
147
|
+
delivered_data << payload
|
148
|
+
end
|
149
|
+
end
|
150
|
+
t.abort_on_exception = true
|
151
|
+
sleep 0.5
|
152
|
+
|
153
|
+
ch = connection.create_channel
|
154
|
+
x = ch.default_exchange
|
155
|
+
x.publish("hello", :routing_key => queue_name)
|
156
|
+
|
157
|
+
sleep 0.7
|
158
|
+
delivered_keys.should include(queue_name)
|
159
|
+
delivered_data.should include("hello")
|
160
|
+
|
161
|
+
ch.queue(queue_name).message_count.should == 0
|
162
|
+
|
163
|
+
ch.close
|
164
|
+
end
|
117
165
|
end
|
118
|
-
|
166
|
+
|
167
|
+
end # describe
|
@@ -2,7 +2,8 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Bunny::Queue, "#pop" do
|
4
4
|
let(:connection) do
|
5
|
-
c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed"
|
5
|
+
c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed",
|
6
|
+
:automatically_recover => false)
|
6
7
|
c.start
|
7
8
|
c
|
8
9
|
end
|
@@ -30,25 +31,6 @@ describe Bunny::Queue, "#pop" do
|
|
30
31
|
end
|
31
32
|
|
32
33
|
|
33
|
-
context "with all defaults and a timeout that is never hit" do
|
34
|
-
it "fetches a messages which is automatically acknowledged" do
|
35
|
-
ch = connection.create_channel
|
36
|
-
|
37
|
-
q = ch.queue("", :exclusive => true)
|
38
|
-
x = ch.default_exchange
|
39
|
-
|
40
|
-
x.publish("xyzzy", :routing_key => q.name)
|
41
|
-
|
42
|
-
sleep(0.5)
|
43
|
-
delivery_info, properties, content = q.pop_waiting(:timeout => 1.0)
|
44
|
-
content.should == "xyzzy"
|
45
|
-
q.message_count.should == 0
|
46
|
-
|
47
|
-
ch.close
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
|
52
34
|
context "with an empty queue" do
|
53
35
|
it "returns an empty response" do
|
54
36
|
ch = connection.create_channel
|
@@ -63,20 +45,4 @@ describe Bunny::Queue, "#pop" do
|
|
63
45
|
ch.close
|
64
46
|
end
|
65
47
|
end
|
66
|
-
|
67
|
-
|
68
|
-
context "with an empty queue and a timeout" do
|
69
|
-
it "raises an exception" do
|
70
|
-
ch = connection.create_channel
|
71
|
-
|
72
|
-
q = ch.queue("", :exclusive => true)
|
73
|
-
q.purge
|
74
|
-
|
75
|
-
lambda {
|
76
|
-
_, _, content = q.pop_waiting(:timeout => 0.5)
|
77
|
-
}.should raise_error(Timeout::Error)
|
78
|
-
|
79
|
-
ch.close
|
80
|
-
end
|
81
|
-
end
|
82
48
|
end
|
@@ -153,27 +153,37 @@ describe Bunny::Session do
|
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
156
|
-
|
157
|
-
|
158
|
-
subject
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
156
|
+
unless ENV["CI"]
|
157
|
+
context "initialized with :ssl => true" do
|
158
|
+
let(:subject) do
|
159
|
+
described_class.new(:user => "bunny_gem",
|
160
|
+
:password => "bunny_password",
|
161
|
+
:vhost => "bunny_testbed",
|
162
|
+
:ssl => true,
|
163
|
+
:ssl_cert => "spec/tls/client_cert.pem",
|
164
|
+
:ssl_key => "spec/tls/client_key.pem",
|
165
|
+
:ssl_ca_certificates => ["./spec/tls/cacert.pem"])
|
166
|
+
end
|
167
167
|
|
168
|
-
|
169
|
-
|
170
|
-
|
168
|
+
it "uses TLS port" do
|
169
|
+
subject.port.should == tls_port
|
170
|
+
end
|
171
171
|
end
|
172
172
|
|
173
|
-
|
173
|
+
context "initialized with :tls => true" do
|
174
|
+
let(:subject) do
|
175
|
+
described_class.new(:user => "bunny_gem",
|
176
|
+
:password => "bunny_password",
|
177
|
+
:vhost => "bunny_testbed",
|
178
|
+
:tls => true,
|
179
|
+
:tls_cert => "spec/tls/client_cert.pem",
|
180
|
+
:tls_key => "spec/tls/client_key.pem",
|
181
|
+
:tls_ca_certificates => ["./spec/tls/cacert.pem"])
|
182
|
+
end
|
174
183
|
|
175
|
-
|
176
|
-
|
184
|
+
it "uses TLS port" do
|
185
|
+
subject.port.should == tls_port
|
186
|
+
end
|
177
187
|
end
|
178
188
|
end
|
179
189
|
|
@@ -346,19 +356,17 @@ describe Bunny::Session do
|
|
346
356
|
|
347
357
|
|
348
358
|
context "initialized with a disconnected host" do
|
349
|
-
subject do
|
350
|
-
described_class.new(:port => 38000)
|
351
|
-
end
|
352
|
-
|
353
359
|
it "fails to connect" do
|
354
360
|
lambda do
|
355
|
-
|
361
|
+
c = described_class.new(:port => 38000)
|
362
|
+
c.start
|
356
363
|
end.should raise_error(Bunny::TCPConnectionFailed)
|
357
364
|
end
|
358
365
|
|
359
366
|
it "is not connected" do
|
360
367
|
begin
|
361
|
-
|
368
|
+
c = described_class.new(:port => 38000)
|
369
|
+
c.start
|
362
370
|
rescue Bunny::TCPConnectionFailed => e
|
363
371
|
true
|
364
372
|
end
|
@@ -368,7 +376,8 @@ describe Bunny::Session do
|
|
368
376
|
|
369
377
|
it "is not open" do
|
370
378
|
begin
|
371
|
-
|
379
|
+
c = described_class.new(:port => 38000)
|
380
|
+
c.start
|
372
381
|
rescue Bunny::TCPConnectionFailed => e
|
373
382
|
true
|
374
383
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bunny
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.0.
|
4
|
+
version: 0.9.0.rc2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Duncan
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2013-06-
|
15
|
+
date: 2013-06-27 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: amq-protocol
|
@@ -28,7 +28,7 @@ dependencies:
|
|
28
28
|
- - '>='
|
29
29
|
- !ruby/object:Gem::Version
|
30
30
|
version: 1.6.0
|
31
|
-
description:
|
31
|
+
description: Easy to use, feature complete Ruby client for RabbitMQ 2.0.
|
32
32
|
email:
|
33
33
|
- celldee@gmail.com
|
34
34
|
- eric@5stops.com
|
@@ -178,7 +178,7 @@ files:
|
|
178
178
|
- spec/unit/concurrent/condition_spec.rb
|
179
179
|
- spec/unit/concurrent/linked_continuation_queue_spec.rb
|
180
180
|
- spec/unit/transport_spec.rb
|
181
|
-
homepage: http://
|
181
|
+
homepage: http://rubybunny.info
|
182
182
|
licenses:
|
183
183
|
- MIT
|
184
184
|
metadata: {}
|