bunny 0.10.0 → 0.10.1

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -1
  3. data/ChangeLog.md +10 -0
  4. data/README.md +5 -5
  5. data/benchmarks/mutex_and_monitor.rb +42 -0
  6. data/lib/bunny/exceptions.rb +4 -1
  7. data/lib/bunny/reader_loop.rb +13 -1
  8. data/lib/bunny/session.rb +13 -2
  9. data/lib/bunny/version.rb +1 -1
  10. data/spec/higher_level_api/integration/basic_cancel_spec.rb +1 -1
  11. data/spec/higher_level_api/integration/basic_consume_spec.rb +1 -1
  12. data/spec/higher_level_api/integration/basic_nack_spec.rb +1 -1
  13. data/spec/higher_level_api/integration/basic_publish_spec.rb +1 -1
  14. data/spec/higher_level_api/integration/basic_qos_spec.rb +5 -8
  15. data/spec/higher_level_api/integration/basic_reject_spec.rb +16 -17
  16. data/spec/higher_level_api/integration/basic_return_spec.rb +1 -1
  17. data/spec/higher_level_api/integration/channel_close_spec.rb +6 -10
  18. data/spec/higher_level_api/integration/channel_flow_spec.rb +6 -9
  19. data/spec/higher_level_api/integration/channel_open_spec.rb +11 -20
  20. data/spec/higher_level_api/integration/confirm_select_spec.rb +1 -1
  21. data/spec/higher_level_api/integration/connection_spec.rb +1 -1
  22. data/spec/higher_level_api/integration/consistent_hash_exchange_spec.rb +1 -1
  23. data/spec/higher_level_api/integration/consumer_cancellation_notification_spec.rb +1 -1
  24. data/spec/higher_level_api/integration/dead_lettering_spec.rb +1 -1
  25. data/spec/higher_level_api/integration/exchange_bind_spec.rb +1 -1
  26. data/spec/higher_level_api/integration/exchange_declare_spec.rb +1 -1
  27. data/spec/higher_level_api/integration/exchange_delete_spec.rb +1 -1
  28. data/spec/higher_level_api/integration/exchange_unbind_spec.rb +1 -1
  29. data/spec/higher_level_api/integration/merry_go_round_spec.rb +1 -1
  30. data/spec/higher_level_api/integration/message_properties_access_spec.rb +1 -1
  31. data/spec/higher_level_api/integration/predeclared_exchanges_spec.rb +1 -1
  32. data/spec/higher_level_api/integration/publishing_edge_cases_spec.rb +1 -1
  33. data/spec/higher_level_api/integration/queue_declare_spec.rb +1 -1
  34. data/spec/higher_level_api/integration/queue_delete_spec.rb +2 -2
  35. data/spec/higher_level_api/integration/queue_purge_spec.rb +1 -1
  36. data/spec/higher_level_api/integration/queue_unbind_spec.rb +2 -2
  37. data/spec/higher_level_api/integration/read_only_consumer_spec.rb +1 -1
  38. data/spec/higher_level_api/integration/sender_selected_distribution_spec.rb +2 -2
  39. data/spec/higher_level_api/integration/tls_connection_spec.rb +2 -2
  40. data/spec/higher_level_api/integration/tx_commit_spec.rb +1 -1
  41. data/spec/higher_level_api/integration/tx_rollback_spec.rb +1 -1
  42. data/spec/stress/connection_open_close_spec.rb +11 -2
  43. data/spec/unit/concurrent/condition_spec.rb +53 -46
  44. data/spec/unit/concurrent/synchronized_sorted_set_spec.rb +48 -9
  45. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0a48be5011527d81ec653d8a687d5ece9ee4138f
4
- data.tar.gz: ccf19ed7b3b9ec42e3e3654c8e5a6ee1cbe772eb
3
+ metadata.gz: d3e5ee2f2801f1420033324361e8fe9768a48e7e
4
+ data.tar.gz: b1f35041c2d32444ab5290301cbab613c4d63abd
5
5
  SHA512:
6
- metadata.gz: bea1acb05abe8f527821d427c8a104d65c5d813996342068f00116a6832d9233d849233251c55e63b1f03b523a8b4d62fed5583cdc49cabff2d580759389c111
7
- data.tar.gz: 51fc965da8fc766e8c55770d15df0d7494c68801001f5e2beb02956432919e7a151d1aa84b581f29c0b59d87d8b8415fe8d972e09ce18c90123f4823bbf96314
6
+ metadata.gz: 35622fd832fd559a594c7eb1bbb46576f1831d34c4bb2a1b9e4ee86e58500afa39e179785388aba9ca3a9311665f193b06d96b10429be7bc33dd6d54f98de706
7
+ data.tar.gz: 9f39c1e15d01f1a09f617a411f7d157028e2efe4cb4eb905564f73a08ff956e2fbbfdb0cb71cb9087aca7b0f3c0082fee348dc9ba41764876d857f2a14fdf7a2
data/.travis.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  bundler_args: --without development
2
2
  before_script: "./bin/ci/before_build.sh"
3
- script: "bundle exec rspec -c spec"
3
+ script: "bundle exec rspec -cfs spec"
4
4
  rvm:
5
5
  - "2.0"
6
6
  - "1.9.3"
@@ -15,3 +15,6 @@ branches:
15
15
  only:
16
16
  - master
17
17
  - 0.9.x-stable
18
+ matrix:
19
+ allow_failures:
20
+ - rvm: rbx-19mode
data/ChangeLog.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## Changes between Bunny 0.10.0 and 0.10.1
2
+
3
+ ### Fix Abnormally Slow Bunny::Connection#close on JRuby
4
+
5
+ `Bunny::Connection#close` on JRuby sometimes could enter a waiting
6
+ state [on a native NIO/kqueue method] that lasted up to over 10 seconds.
7
+
8
+ This severely affected test suite run times.
9
+
10
+
1
11
  ## Changes between Bunny 0.9.0 and 0.10.0
2
12
 
3
13
  This release has one minor **breaking API change**.
data/README.md CHANGED
@@ -79,7 +79,7 @@ backwards compatible as possible but within reason.
79
79
 
80
80
  ### With Rubygems
81
81
 
82
- To install Bunny 0.9.x with RubyGems:
82
+ To install Bunny with RubyGems:
83
83
 
84
84
  ```
85
85
  gem install bunny
@@ -87,17 +87,17 @@ gem install bunny
87
87
 
88
88
  ### Bundler Dependency
89
89
 
90
- To use Bunny 0.9.x in a project managed with Bundler:
90
+ To use Bunny in a project managed with Bundler:
91
91
 
92
92
  ``` ruby
93
- gem "bunny", ">= 0.9.3"
93
+ gem "bunny", ">= 0.10.0"
94
94
  ```
95
95
 
96
96
 
97
- ## Quick Start for Bunny 0.9.x
97
+ ## Quick Start
98
98
 
99
99
  Below is a small snippet that demonstrates how to publish
100
- and synchronously consume ("pull API") messages with Bunny 0.9.
100
+ and synchronously consume ("pull API") messages with Bunny.
101
101
 
102
102
  For a 15 minute tutorial using more practical examples, see [Getting Started with RabbitMQ and Ruby using Bunny](http://rubybunny.info/articles/getting_started.html).
103
103
 
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require "rubygems"
5
+ require "set"
6
+ require "thread"
7
+ require "benchmark"
8
+ require "monitor"
9
+
10
+ puts
11
+ puts "-" * 80
12
+ puts "Benchmarking on #{RUBY_DESCRIPTION}"
13
+
14
+ n = 2_000_000
15
+ mx = Mutex.new
16
+ mt = Monitor.new
17
+
18
+ # warm up the JIT, etc
19
+ puts "Doing a warmup run..."
20
+ n.times do |i|
21
+ mx.synchronize { 1 }
22
+ mt.synchronize { 1 }
23
+ end
24
+
25
+ t1 = Benchmark.realtime do
26
+ n.times do |i|
27
+ mx.synchronize { 1 }
28
+ end
29
+ end
30
+ r1 = (n.to_f/t1.to_f)
31
+
32
+ t2 = Benchmark.realtime do
33
+ n.times do |i|
34
+ mt.synchronize { 1 }
35
+ end
36
+ end
37
+ r2 = (n.to_f/t2.to_f)
38
+
39
+ puts "Mutex#synchronize, rate: #{(r1 / 1000).round(2)} KGHz"
40
+ puts "Monitor#synchronize, rate: #{(r2 / 1000).round(2)} KGHz"
41
+ puts
42
+ puts "-" * 80
@@ -55,7 +55,7 @@ module Bunny
55
55
  when Exception then
56
56
  e.message
57
57
  end
58
- super("Could not estabilish TCP connection to #{hostname}:#{port}: #{m}")
58
+ super("Could not establish TCP connection to #{hostname}:#{port}: #{m}")
59
59
  end
60
60
  end
61
61
 
@@ -70,6 +70,9 @@ module Bunny
70
70
  end
71
71
  end
72
72
 
73
+ class ShutdownSignal < Exception
74
+ end
75
+
73
76
  # Raised when RabbitMQ closes TCP connection before finishing connection
74
77
  # sequence properly. This typically indicates an authentication issue.
75
78
  class PossibleAuthenticationFailureError < Exception
@@ -19,7 +19,6 @@ module Bunny
19
19
 
20
20
  def start
21
21
  @thread = Thread.new(&method(:run_loop))
22
- @thread.abort_on_exception = true
23
22
  end
24
23
 
25
24
  def resume
@@ -33,8 +32,10 @@ module Bunny
33
32
  break if @stopping || @network_is_down
34
33
  run_once
35
34
  rescue Errno::EBADF => ebadf
35
+ break if @stopping
36
36
  # ignored, happens when we loop after the transport has already been closed
37
37
  rescue AMQ::Protocol::EmptyResponseError, IOError, SystemCallError => e
38
+ break if @stopping
38
39
  log_exception(e)
39
40
 
40
41
  @network_is_down = true
@@ -44,7 +45,10 @@ module Bunny
44
45
  else
45
46
  @session_thread.raise(Bunny::NetworkFailure.new("detected a network failure: #{e.message}", e))
46
47
  end
48
+ rescue ShutdownSignal => _
49
+ break
47
50
  rescue Exception => e
51
+ break if @stopping
48
52
  log_exception(e)
49
53
 
50
54
  @network_is_down = true
@@ -86,6 +90,14 @@ module Bunny
86
90
  @stopped
87
91
  end
88
92
 
93
+ def raise(e)
94
+ @thread.raise(e)
95
+ end
96
+
97
+ def join
98
+ @thread.join
99
+ end
100
+
89
101
  def kill
90
102
  @thread.kill
91
103
  @thread.join
data/lib/bunny/session.rb CHANGED
@@ -269,7 +269,9 @@ module Bunny
269
269
  self.close_connection(true)
270
270
  end
271
271
 
272
+ # puts "before maybe_shutdown_reader_loop"
272
273
  maybe_shutdown_reader_loop
274
+ # puts "after maybe_shutdown_reader_loop"
273
275
  close_transport
274
276
 
275
277
  @status = :closed
@@ -626,10 +628,19 @@ module Bunny
626
628
  def maybe_shutdown_reader_loop
627
629
  if @reader_loop
628
630
  @reader_loop.stop
629
- # We don't need to kill the loop but
630
631
  # this is the easiest way to wait until the loop
631
632
  # is guaranteed to have terminated
632
- @reader_loop.kill
633
+ @reader_loop.raise(ShutdownSignal)
634
+ # joining the thread here may take forever
635
+ # on JRuby because sun.nio.ch.KQueueArrayWrapper#kevent0 is
636
+ # a native method that cannot be (easily) interrupted.
637
+ # So we use this ugly hack or else our test suite takes forever
638
+ # to run on JRuby (a new connection is opened/closed per example). MK.
639
+ if RUBY_ENGINE == "jruby"
640
+ sleep 0.075
641
+ else
642
+ @reader_loop.join
643
+ end
633
644
  end
634
645
 
635
646
  @reader_loop = nil
data/lib/bunny/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Bunny
4
4
  # @return [String] Version of the library
5
- VERSION = "0.10.0"
5
+ VERSION = "0.10.1"
6
6
  end
@@ -7,7 +7,7 @@ describe Bunny::Consumer, "#cancel" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -8,7 +8,7 @@ describe Bunny::Queue, "#subscribe" do
8
8
  c
9
9
  end
10
10
 
11
- after :all do
11
+ after :each do
12
12
  connection.close if connection.open?
13
13
  end
14
14
 
@@ -7,7 +7,7 @@ describe Bunny::Channel, "#nack" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -8,7 +8,7 @@ if RUBY_VERSION <= "1.9"
8
8
  c
9
9
  end
10
10
 
11
- after :all do
11
+ after :each do
12
12
  connection.close if connection.open?
13
13
  end
14
14
 
@@ -7,25 +7,22 @@ describe Bunny::Channel, "#prefetch" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close
12
12
  end
13
13
 
14
-
15
- subject do
16
- connection.create_channel
17
- end
18
-
19
14
  context "with a positive integer" do
20
15
  it "sets that prefetch level via basic.qos" do
21
- subject.prefetch(10).should be_instance_of(AMQ::Protocol::Basic::QosOk)
16
+ ch = connection.create_channel
17
+ ch.prefetch(10).should be_instance_of(AMQ::Protocol::Basic::QosOk)
22
18
  end
23
19
  end
24
20
 
25
21
  context "with a negative integer" do
26
22
  it "raises an ArgumentError" do
23
+ ch = connection.create_channel
27
24
  expect {
28
- subject.prefetch(-2)
25
+ ch.prefetch(-2)
29
26
  }.to raise_error(ArgumentError)
30
27
  end
31
28
  end
@@ -7,65 +7,64 @@ describe Bunny::Channel, "#reject" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
14
- subject do
15
- connection.create_channel
16
- end
17
-
18
14
  context "with requeue = true" do
19
15
  it "requeues a message" do
20
- q = subject.queue("bunny.basic.reject.manual-acks", :exclusive => true)
21
- x = subject.default_exchange
16
+ ch = connection.create_channel
17
+ q = ch.queue("bunny.basic.reject.manual-acks", :exclusive => true)
18
+ x = ch.default_exchange
22
19
 
23
20
  x.publish("bunneth", :routing_key => q.name)
24
21
  sleep(0.5)
25
22
  q.message_count.should == 1
26
23
  delivery_info, _, _ = q.pop(:ack => true)
27
24
 
28
- subject.reject(delivery_info.delivery_tag, true)
25
+ ch.reject(delivery_info.delivery_tag, true)
29
26
  sleep(0.5)
30
27
  q.message_count.should == 1
31
28
 
32
- subject.close
29
+ ch.close
33
30
  end
34
31
  end
35
32
 
36
33
  context "with requeue = false" do
37
34
  it "rejects a message" do
38
- q = subject.queue("bunny.basic.reject.with-requeue-false", :exclusive => true)
39
- x = subject.default_exchange
35
+ ch = connection.create_channel
36
+ q = ch.queue("bunny.basic.reject.with-requeue-false", :exclusive => true)
37
+ x = ch.default_exchange
40
38
 
41
39
  x.publish("bunneth", :routing_key => q.name)
42
40
  sleep(0.5)
43
41
  q.message_count.should == 1
44
42
  delivery_info, _, _ = q.pop(:ack => true)
45
43
 
46
- subject.reject(delivery_info.delivery_tag, false)
44
+ ch.reject(delivery_info.delivery_tag, false)
47
45
  sleep(0.5)
48
46
  q.message_count.should == 0
49
47
 
50
- subject.close
48
+ ch.close
51
49
  end
52
50
  end
53
51
 
54
52
 
55
53
  context "with an invalid (random) delivery tag" do
56
54
  it "causes a channel-level error" do
57
- q = subject.queue("bunny.basic.reject.unknown-delivery-tag", :exclusive => true)
58
- x = subject.default_exchange
55
+ ch = connection.create_channel
56
+ q = ch.queue("bunny.basic.reject.unknown-delivery-tag", :exclusive => true)
57
+ x = ch.default_exchange
59
58
 
60
59
  x.publish("bunneth", :routing_key => q.name)
61
60
  sleep(0.25)
62
61
  q.message_count.should == 1
63
62
  _, _, content = q.pop(:ack => true)
64
63
 
65
- subject.on_error do |ch, channel_close|
64
+ ch.on_error do |ch, channel_close|
66
65
  @channel_close = channel_close
67
66
  end
68
- subject.reject(82, true)
67
+ ch.reject(82, true)
69
68
 
70
69
  sleep 0.5
71
70
 
@@ -7,7 +7,7 @@ describe Bunny::Exchange, "#publish" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -7,21 +7,17 @@ describe Bunny::Channel, "when closed" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close
12
12
  end
13
13
 
14
-
15
- subject do
16
- connection.create_channel
17
- end
18
-
19
14
  it "releases the id" do
20
- n = subject.number
15
+ ch = connection.create_channel
16
+ n = ch.number
21
17
 
22
- subject.should be_open
23
- subject.close
24
- subject.should be_closed
18
+ ch.should be_open
19
+ ch.close
20
+ ch.should be_closed
25
21
 
26
22
  # a new channel with the same id can be created
27
23
  connection.create_channel(n)
@@ -7,18 +7,15 @@ describe Bunny::Channel, "#flow" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close
12
12
  end
13
13
 
14
-
15
- subject do
16
- connection.create_channel
17
- end
18
-
19
14
  it "is supported" do
20
- subject.flow(true).should be_instance_of(AMQ::Protocol::Channel::FlowOk)
21
- subject.flow(false).should be_instance_of(AMQ::Protocol::Channel::FlowOk)
22
- subject.flow(true).should be_instance_of(AMQ::Protocol::Channel::FlowOk)
15
+ ch = connection.create_channel
16
+
17
+ ch.flow(true).should be_instance_of(AMQ::Protocol::Channel::FlowOk)
18
+ ch.flow(false).should be_instance_of(AMQ::Protocol::Channel::FlowOk)
19
+ ch.flow(true).should be_instance_of(AMQ::Protocol::Channel::FlowOk)
23
20
  end
24
21
  end
@@ -7,51 +7,42 @@ describe Bunny::Channel, "when opened" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close
12
12
  end
13
13
 
14
14
  context "without explicitly provided id" do
15
- subject do
16
- connection.create_channel
17
- end
18
-
19
15
  it "gets an allocated id and is successfully opened" do
20
16
  connection.should be_connected
21
- subject.should be_open
17
+ ch = connection.create_channel
18
+ ch.should be_open
22
19
 
23
- subject.id.should be > 0
20
+ ch.id.should be > 0
24
21
  end
25
22
  end
26
23
 
27
24
 
28
25
  context "with explicitly provided id" do
29
- subject do
30
- connection.create_channel(767)
31
- end
32
-
33
26
  it "uses that id and is successfully opened" do
27
+ ch = connection.create_channel(767)
34
28
  connection.should be_connected
35
- subject.should be_open
29
+ ch.should be_open
36
30
 
37
- subject.id.should == 767
31
+ ch.id.should == 767
38
32
  end
39
33
  end
40
34
 
41
35
 
42
36
 
43
37
  context "with explicitly provided id that is already taken" do
44
- subject do
45
- connection.create_channel(767)
46
- end
47
-
48
38
  it "reuses the channel that is already opened" do
39
+ ch = connection.create_channel(767)
49
40
  connection.should be_connected
50
- subject.should be_open
41
+ ch.should be_open
51
42
 
52
- subject.id.should == 767
43
+ ch.id.should == 767
53
44
 
54
- connection.create_channel(767).should == subject
45
+ connection.create_channel(767).should == ch
55
46
  end
56
47
  end
57
48
  end
@@ -7,7 +7,7 @@ describe Bunny::Channel, "#confirm_select" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -284,7 +284,7 @@ describe Bunny::Session do
284
284
 
285
285
 
286
286
  context "initialized with :host => 127.0.0.1 and non-default credentials (take 2)" do
287
- after :all do
287
+ after :each do
288
288
  subject.close if subject.open?
289
289
  end
290
290
 
@@ -9,7 +9,7 @@ unless ENV["CI"]
9
9
  c
10
10
  end
11
11
 
12
- after :all do
12
+ after :each do
13
13
  connection.close
14
14
  end
15
15
 
@@ -7,7 +7,7 @@ describe Bunny::Channel do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ describe "A message" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ describe Bunny::Exchange do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ describe Bunny::Exchange do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ describe Bunny::Exchange, "#delete" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ describe Bunny::Exchange do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -31,7 +31,7 @@ describe "A message that is proxied by multiple intermediate consumers" do
31
31
  c
32
32
  end
33
33
 
34
- after :all do
34
+ after :each do
35
35
  [c1, c2, c3, c4, c5].each do |c|
36
36
  c.close if c.open?
37
37
  end
@@ -7,7 +7,7 @@ describe Bunny::Queue, "#subscribe" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ describe "amq.* exchanges" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -11,7 +11,7 @@ unless ENV["CI"]
11
11
  c
12
12
  end
13
13
 
14
- after :all do
14
+ after :each do
15
15
  connection.close if connection.open?
16
16
  end
17
17
 
@@ -7,7 +7,7 @@ describe Bunny::Queue do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ describe Bunny::Queue, "#delete" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close
12
12
  end
13
13
 
@@ -22,7 +22,7 @@ describe Bunny::Queue, "#delete" do
22
22
  expect {
23
23
  q.delete
24
24
  }.to raise_error(Bunny::NotFound)
25
-
25
+
26
26
  ch.queues.size.should == 0
27
27
  end
28
28
  end
@@ -7,7 +7,7 @@ describe Bunny::Queue do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ describe Bunny::Queue, "bound to an exchange" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close
12
12
  end
13
13
 
@@ -37,7 +37,7 @@ describe Bunny::Queue, "NOT bound to an exchange" do
37
37
  c
38
38
  end
39
39
 
40
- after :all do
40
+ after :each do
41
41
  connection.close
42
42
  end
43
43
 
@@ -13,7 +13,7 @@ describe Bunny::Queue, "#subscribe" do
13
13
  c
14
14
  end
15
15
 
16
- after :all do
16
+ after :each do
17
17
  publisher_connection.close if publisher_connection.open?
18
18
  consumer_connection.close if consumer_connection.open?
19
19
  end
@@ -7,7 +7,7 @@ describe "Sender-selected distribution" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -23,7 +23,7 @@ describe "Sender-selected distribution" do
23
23
  n.times do |i|
24
24
  x.publish("Message #{i}", :routing_key => "one", :headers => {"CC" => ["two", "three"]})
25
25
  end
26
-
26
+
27
27
  sleep 0.5
28
28
 
29
29
  q1.message_count.should == n
@@ -15,7 +15,7 @@ unless ENV["CI"]
15
15
  c
16
16
  end
17
17
 
18
- after :all do
18
+ after :each do
19
19
  connection.close
20
20
  end
21
21
 
@@ -57,7 +57,7 @@ unless ENV["CI"]
57
57
  c
58
58
  end
59
59
 
60
- after :all do
60
+ after :each do
61
61
  connection.close
62
62
  end
63
63
 
@@ -7,7 +7,7 @@ describe Bunny::Channel, "#tx_commit" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -7,7 +7,7 @@ describe Bunny::Channel, "#tx_rollback" do
7
7
  c
8
8
  end
9
9
 
10
- after :all do
10
+ after :each do
11
11
  connection.close if connection.open?
12
12
  end
13
13
 
@@ -1,8 +1,17 @@
1
1
  require "spec_helper"
2
2
 
3
- unless RUBY_ENGINE == "jruby"
3
+ unless RUBY_ENGINE == "jruby" && !ENV["FORCE_JRUBY_RUN"]
4
4
  describe Bunny::Session do
5
- 4000.times do |i|
5
+ # creating thousands of connections means creating
6
+ # twice as many threads and this won't fly with the JVM
7
+ # in CI containers. MK.
8
+ n = if RUBY_ENGINE == "jruby"
9
+ 250
10
+ else
11
+ 2500
12
+ end
13
+
14
+ n.times do |i|
6
15
  it "can be closed (take #{i})" do
7
16
  c = Bunny.new(:automatically_recover => false)
8
17
  c.start
@@ -2,73 +2,80 @@ require "spec_helper"
2
2
  require "bunny/concurrent/condition"
3
3
 
4
4
  describe Bunny::Concurrent::Condition do
5
+
5
6
  describe "#wait" do
6
- it "blocks current thread until notified" do
7
- condition = described_class.new
8
- xs = []
7
+ 100.times do |i|
8
+ it "blocks current thread until notified (take #{i})" do
9
+ condition = described_class.new
10
+ xs = []
9
11
 
10
- t = Thread.new do
11
- xs << :notified
12
+ t = Thread.new do
13
+ xs << :notified
12
14
 
13
- sleep 0.25
14
- condition.notify
15
- end
16
- t.abort_on_exception = true
15
+ sleep 0.25
16
+ condition.notify
17
+ end
18
+ t.abort_on_exception = true
17
19
 
18
- condition.wait
19
- xs.should == [:notified]
20
+ condition.wait
21
+ xs.should == [:notified]
22
+ end
20
23
  end
21
24
  end
22
25
 
23
26
  describe "#notify" do
24
- it "notifies a single thread waiting on the latch" do
25
- mutex = Mutex.new
26
- condition = described_class.new
27
- xs = []
27
+ 100.times do |i|
28
+ it "notifies a single thread waiting on the latch (take #{i})" do
29
+ mutex = Mutex.new
30
+ condition = described_class.new
31
+ xs = []
28
32
 
29
- t1 = Thread.new do
30
- condition.wait
31
- mutex.synchronize { xs << :notified1 }
32
- end
33
- t1.abort_on_exception = true
33
+ t1 = Thread.new do
34
+ condition.wait
35
+ mutex.synchronize { xs << :notified1 }
36
+ end
37
+ t1.abort_on_exception = true
34
38
 
35
- t2 = Thread.new do
36
- condition.wait
37
- mutex.synchronize { xs << :notified2 }
38
- end
39
- t2.abort_on_exception = true
39
+ t2 = Thread.new do
40
+ condition.wait
41
+ mutex.synchronize { xs << :notified2 }
42
+ end
43
+ t2.abort_on_exception = true
40
44
 
41
- sleep 0.25
42
- condition.notify
43
- sleep 0.5
44
- xs.should satisfy { |ys| ys.size == 1 && (ys.include?(:notified1) || ys.include?(:notified2)) }
45
+ sleep 0.25
46
+ condition.notify
47
+ sleep 0.5
48
+ xs.should satisfy { |ys| ys.size == 1 && (ys.include?(:notified1) || ys.include?(:notified2)) }
49
+ end
45
50
  end
46
51
  end
47
52
 
48
53
  describe "#notify_all" do
49
- let(:n) { 120 }
54
+ let(:n) { 30 }
50
55
 
51
- it "notifies all the threads waiting on the latch" do
52
- mutex = Mutex.new
53
- condition = described_class.new
54
- @xs = []
56
+ 100.times do |i|
57
+ it "notifies all the threads waiting on the latch (take #{i})" do
58
+ mutex = Mutex.new
59
+ condition = described_class.new
60
+ @xs = []
55
61
 
56
- n.times do |i|
57
- t = Thread.new do
58
- condition.wait
59
- mutex.synchronize { @xs << "notified#{i + 1}".to_sym }
62
+ n.times do |i|
63
+ t = Thread.new do
64
+ condition.wait
65
+ mutex.synchronize { @xs << "notified#{i + 1}".to_sym }
66
+ end
67
+ t.abort_on_exception = true
60
68
  end
61
- t.abort_on_exception = true
62
- end
63
69
 
64
- sleep 0.5
65
- condition.notify_all
66
- sleep 0.5
70
+ sleep 0.5
71
+ condition.notify_all
72
+ sleep 0.5
67
73
 
68
- n.times do |i|
69
- item = "notified#{i + 1}".to_sym
74
+ n.times do |i|
75
+ item = "notified#{i + 1}".to_sym
70
76
 
71
- @xs.should include(item)
77
+ @xs.should include(item)
78
+ end
72
79
  end
73
80
  end
74
81
  end
@@ -1,34 +1,73 @@
1
1
  require "spec_helper"
2
2
  require "bunny/concurrent/synchronized_sorted_set"
3
3
 
4
- describe Bunny::Concurrent::SynchronizedSortedSet do
5
- it "synchronizes common operations needed by Bunny" do
6
- s = described_class.new
7
- s.length.should == 0
4
+ unless ENV["CI"]
5
+ describe Bunny::Concurrent::SynchronizedSortedSet do
6
+ 50.times do |i|
7
+ it "provides the same API as SortedSet for key operations (take #{i})" do
8
+ s = described_class.new
9
+ s.length.should == 0
8
10
 
9
- 10.times do
10
- Thread.new do
11
11
  s << 1
12
+ s.length.should == 1
12
13
  s << 1
14
+ s.length.should == 1
13
15
  s << 2
16
+ s.length.should == 2
14
17
  s << 3
18
+ s.length.should == 3
15
19
  s << 4
20
+ s.length.should == 4
16
21
  s << 4
17
22
  s << 4
18
23
  s << 4
24
+ s.length.should == 4
19
25
  s << 5
26
+ s.length.should == 5
20
27
  s << 5
21
28
  s << 5
22
29
  s << 5
30
+ s.length.should == 5
23
31
  s << 6
32
+ s.length.should == 6
24
33
  s << 7
34
+ s.length.should == 7
25
35
  s << 8
36
+ s.length.should == 8
26
37
  s.delete 8
38
+ s.length.should == 7
27
39
  s.delete_if { |i| i == 1 }
40
+ s.length.should == 6
28
41
  end
29
- end
30
- sleep 2.0
42
+ it "synchronizes common operations needed by Bunny (take #{i})" do
43
+ s = described_class.new
44
+ s.length.should == 0
45
+
46
+ 10.times do
47
+ Thread.new do
48
+ s << 1
49
+ s << 1
50
+ s << 2
51
+ s << 3
52
+ s << 4
53
+ s << 4
54
+ s << 4
55
+ s << 4
56
+ s << 5
57
+ s << 5
58
+ s << 5
59
+ s << 5
60
+ s << 6
61
+ s << 7
62
+ s << 8
63
+ s.delete 8
64
+ s.delete_if { |i| i == 1 }
65
+ end
66
+ end
67
+ sleep 0.5
31
68
 
32
- s.length.should == 6
69
+ s.length.should == 6
70
+ end
71
+ end
33
72
  end
34
73
  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.10.0
4
+ version: 0.10.1
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-08-03 00:00:00.000000000 Z
15
+ date: 2013-08-07 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: amq-protocol
@@ -54,6 +54,7 @@ files:
54
54
  - benchmarks/basic_publish/with_4K_messages.rb
55
55
  - benchmarks/basic_publish/with_64K_messages.rb
56
56
  - benchmarks/channel_open.rb
57
+ - benchmarks/mutex_and_monitor.rb
57
58
  - benchmarks/queue_declare.rb
58
59
  - benchmarks/queue_declare_and_bind.rb
59
60
  - benchmarks/queue_declare_bind_and_delete.rb