bunny 0.10.0 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
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