bunny 2.19.0 → 2.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -32
  3. data/lib/bunny/channel.rb +86 -10
  4. data/lib/bunny/consumer.rb +2 -2
  5. data/lib/bunny/delivery_info.rb +1 -1
  6. data/lib/bunny/queue.rb +33 -2
  7. data/lib/bunny/session.rb +1 -1
  8. data/lib/bunny/transport.rb +30 -1
  9. data/lib/bunny/version.rb +1 -1
  10. data/lib/bunny.rb +45 -4
  11. metadata +4 -144
  12. data/spec/config/enabled_plugins +0 -1
  13. data/spec/config/rabbitmq.conf +0 -13
  14. data/spec/higher_level_api/integration/basic_ack_spec.rb +0 -230
  15. data/spec/higher_level_api/integration/basic_cancel_spec.rb +0 -142
  16. data/spec/higher_level_api/integration/basic_consume_spec.rb +0 -357
  17. data/spec/higher_level_api/integration/basic_consume_with_objects_spec.rb +0 -54
  18. data/spec/higher_level_api/integration/basic_get_spec.rb +0 -80
  19. data/spec/higher_level_api/integration/basic_nack_spec.rb +0 -82
  20. data/spec/higher_level_api/integration/basic_publish_spec.rb +0 -74
  21. data/spec/higher_level_api/integration/basic_qos_spec.rb +0 -57
  22. data/spec/higher_level_api/integration/basic_reject_spec.rb +0 -152
  23. data/spec/higher_level_api/integration/basic_return_spec.rb +0 -33
  24. data/spec/higher_level_api/integration/channel_close_spec.rb +0 -66
  25. data/spec/higher_level_api/integration/channel_open_spec.rb +0 -57
  26. data/spec/higher_level_api/integration/connection_recovery_spec.rb +0 -483
  27. data/spec/higher_level_api/integration/connection_spec.rb +0 -589
  28. data/spec/higher_level_api/integration/connection_stop_spec.rb +0 -83
  29. data/spec/higher_level_api/integration/consumer_cancellation_notification_spec.rb +0 -128
  30. data/spec/higher_level_api/integration/dead_lettering_spec.rb +0 -75
  31. data/spec/higher_level_api/integration/exchange_bind_spec.rb +0 -31
  32. data/spec/higher_level_api/integration/exchange_declare_spec.rb +0 -237
  33. data/spec/higher_level_api/integration/exchange_delete_spec.rb +0 -105
  34. data/spec/higher_level_api/integration/exchange_unbind_spec.rb +0 -40
  35. data/spec/higher_level_api/integration/exclusive_queue_spec.rb +0 -28
  36. data/spec/higher_level_api/integration/heartbeat_spec.rb +0 -49
  37. data/spec/higher_level_api/integration/message_properties_access_spec.rb +0 -95
  38. data/spec/higher_level_api/integration/predeclared_exchanges_spec.rb +0 -24
  39. data/spec/higher_level_api/integration/publisher_confirms_spec.rb +0 -191
  40. data/spec/higher_level_api/integration/publishing_edge_cases_spec.rb +0 -87
  41. data/spec/higher_level_api/integration/queue_bind_spec.rb +0 -109
  42. data/spec/higher_level_api/integration/queue_declare_spec.rb +0 -285
  43. data/spec/higher_level_api/integration/queue_delete_spec.rb +0 -41
  44. data/spec/higher_level_api/integration/queue_purge_spec.rb +0 -30
  45. data/spec/higher_level_api/integration/queue_unbind_spec.rb +0 -54
  46. data/spec/higher_level_api/integration/read_only_consumer_spec.rb +0 -60
  47. data/spec/higher_level_api/integration/sender_selected_distribution_spec.rb +0 -36
  48. data/spec/higher_level_api/integration/tls_connection_spec.rb +0 -255
  49. data/spec/higher_level_api/integration/toxiproxy_spec.rb +0 -76
  50. data/spec/higher_level_api/integration/tx_commit_spec.rb +0 -21
  51. data/spec/higher_level_api/integration/tx_rollback_spec.rb +0 -21
  52. data/spec/higher_level_api/integration/with_channel_spec.rb +0 -25
  53. data/spec/issues/issue100_spec.rb +0 -42
  54. data/spec/issues/issue141_spec.rb +0 -43
  55. data/spec/issues/issue202_spec.rb +0 -15
  56. data/spec/issues/issue224_spec.rb +0 -40
  57. data/spec/issues/issue465_spec.rb +0 -32
  58. data/spec/issues/issue549_spec.rb +0 -30
  59. data/spec/issues/issue609_spec.rb +0 -84
  60. data/spec/issues/issue78_spec.rb +0 -72
  61. data/spec/issues/issue83_spec.rb +0 -30
  62. data/spec/issues/issue97_attachment.json +0 -1
  63. data/spec/issues/issue97_spec.rb +0 -175
  64. data/spec/lower_level_api/integration/basic_cancel_spec.rb +0 -83
  65. data/spec/lower_level_api/integration/basic_consume_spec.rb +0 -99
  66. data/spec/spec_helper.rb +0 -47
  67. data/spec/stress/channel_close_stress_spec.rb +0 -64
  68. data/spec/stress/channel_open_stress_spec.rb +0 -84
  69. data/spec/stress/channel_open_stress_with_single_threaded_connection_spec.rb +0 -28
  70. data/spec/stress/concurrent_consumers_stress_spec.rb +0 -71
  71. data/spec/stress/concurrent_publishers_stress_spec.rb +0 -54
  72. data/spec/stress/connection_open_close_spec.rb +0 -52
  73. data/spec/stress/merry_go_round_spec.rb +0 -105
  74. data/spec/toxiproxy_helper.rb +0 -28
  75. data/spec/unit/bunny_spec.rb +0 -15
  76. data/spec/unit/concurrent/atomic_fixnum_spec.rb +0 -35
  77. data/spec/unit/concurrent/condition_spec.rb +0 -82
  78. data/spec/unit/concurrent/linked_continuation_queue_spec.rb +0 -35
  79. data/spec/unit/concurrent/synchronized_sorted_set_spec.rb +0 -73
  80. data/spec/unit/exchange_recovery_spec.rb +0 -39
  81. data/spec/unit/version_delivery_tag_spec.rb +0 -28
@@ -1,52 +0,0 @@
1
- require "spec_helper"
2
-
3
- unless defined?(JRUBY_VERSION) && !ENV["FORCE_JRUBY_RUN"]
4
- describe Bunny::Session do
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 defined?(JRUBY_VERSION)
9
- 250
10
- else
11
- 2500
12
- end
13
-
14
- n.times do |i|
15
- it "can be closed (automatic recovery disabled, take #{i})" do
16
- c = Bunny.new(automatically_recover: false)
17
- c.start
18
- ch = c.create_channel
19
-
20
- expect(c).to be_connected
21
- c.stop
22
- expect(c).to be_closed
23
- end
24
- end
25
-
26
- n.times do |i|
27
- it "can be closed (automatic recovery enabled, take #{i})" do
28
- c = Bunny.new(automatically_recover: true)
29
- c.start
30
- ch = c.create_channel
31
-
32
- expect(c).to be_connected
33
- c.stop
34
- expect(c).to be_closed
35
- end
36
- end
37
-
38
- context "in the single threaded mode" do
39
- n.times do |i|
40
- it "can be closed (single threaded mode, take #{i})" do
41
- c = Bunny.new(automatically_recover: false, threaded: false)
42
- c.start
43
- ch = c.create_channel
44
-
45
- expect(c).to be_connected
46
- c.stop
47
- expect(c).to be_closed
48
- end
49
- end
50
- end
51
- end
52
- end
@@ -1,105 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "A batch of messages proxied by multiple intermediate consumers" do
4
- let(:c1) do
5
- c = Bunny.new(username: "bunny_gem",
6
- password: "bunny_password",
7
- vhost: "bunny_testbed",
8
- heartbeat_timeout: 6)
9
- c.start
10
- c
11
- end
12
-
13
- let(:c2) do
14
- c = Bunny.new(username: "bunny_gem",
15
- password: "bunny_password",
16
- vhost: "bunny_testbed",
17
- heartbeat_timeout: 6)
18
- c.start
19
- c
20
- end
21
-
22
- let(:c3) do
23
- c = Bunny.new(username: "bunny_gem",
24
- password: "bunny_password",
25
- vhost: "bunny_testbed",
26
- heartbeat_timeout: 6)
27
- c.start
28
- c
29
- end
30
-
31
- let(:c4) do
32
- c = Bunny.new(username: "bunny_gem",
33
- password: "bunny_password",
34
- vhost: "bunny_testbed",
35
- heartbeat_timeout: 6)
36
- c.start
37
- c
38
- end
39
-
40
- let(:c5) do
41
- c = Bunny.new(username: "bunny_gem",
42
- password: "bunny_password",
43
- vhost: "bunny_testbed",
44
- heartbeat_timeout: 6)
45
- c.start
46
- c
47
- end
48
-
49
- after :each do
50
- [c1, c2, c3, c4, c5].each do |c|
51
- c.close if c.open?
52
- end
53
- end
54
-
55
- [1000, 5_000, 10_000, 20_000, 30_000, 50_000].each do |n|
56
- # message flow is as follows:
57
- #
58
- # x => q4 => q3 => q2 => q1 => xs (results)
59
- it "successfully reaches its final destination (batch size: #{n})" do
60
- xs = []
61
-
62
- ch1 = c1.create_channel
63
- q1 = ch1.queue("", exclusive: true)
64
- q1.subscribe(manual_ack: true) do |delivery_info, _, payload|
65
- xs << payload
66
- ch1.ack(delivery_info.delivery_tag)
67
- end
68
-
69
- ch2 = c2.create_channel
70
- q2 = ch2.queue("", exclusive: true)
71
- q2.subscribe do |_, _, payload|
72
- q1.publish(payload)
73
- end
74
-
75
- ch3 = c3.create_channel(nil, 2)
76
- q3 = ch3.queue("", exclusive: true)
77
- q3.subscribe(manual_ack: true) do |delivery_info, _, payload|
78
- q2.publish(payload)
79
- ch3.ack(delivery_info.delivery_tag)
80
- end
81
-
82
- ch4 = c4.create_channel(nil, 4)
83
- q4 = ch4.queue("", exclusive: true)
84
- q4.subscribe do |_, _, payload|
85
- q3.publish(payload)
86
- end
87
-
88
- ch5 = c5.create_channel(nil, 8)
89
- x = ch5.default_exchange
90
-
91
- n.times do |i|
92
- x.publish("msg #{i}", routing_key: q4.name)
93
- end
94
-
95
- Bunny::TestKit.poll_until(90) do
96
- xs.size >= n
97
- end
98
-
99
- expect(xs.size).to eq n
100
- expect(xs.last).to eq "msg #{n - 1}"
101
-
102
- [q1, q2, q3, q4].each { |q| q.delete }
103
- end
104
- end
105
- end
@@ -1,28 +0,0 @@
1
- module RabbitMQ
2
- module Toxiproxy
3
- RABBITMQ_UPSTREAM_HOST = if !ENV["LOCAL_RABBITMQ"].nil?
4
- # a local Toxiproxy/RabbitMQ combination
5
- "localhost"
6
- else
7
- # docker-compose
8
- "rabbitmq"
9
- end
10
-
11
- def setup_toxiproxy
12
- ::Toxiproxy.populate([{
13
- name: "rabbitmq",
14
- listen: "0.0.0.0:11111",
15
- upstream: "#{RABBITMQ_UPSTREAM_HOST}:5672"
16
- }])
17
- rabbitmq_toxiproxy.enable
18
- end
19
-
20
- def cleanup_toxiproxy
21
- ::Toxiproxy.populate()
22
- end
23
-
24
- def rabbitmq_toxiproxy
25
- ::Toxiproxy[/rabbitmq/]
26
- end
27
- end
28
- end
@@ -1,15 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe Bunny do
4
- it "has library version" do
5
- expect(Bunny::VERSION).not_to be_nil
6
- expect(Bunny.version).not_to be_nil
7
- end
8
-
9
-
10
- it "has AMQP protocol version" do
11
- expect(Bunny::PROTOCOL_VERSION).to eq "0.9.1"
12
- expect(AMQ::Protocol::PROTOCOL_VERSION).to eq "0.9.1"
13
- expect(Bunny.protocol_version).to eq "0.9.1"
14
- end
15
- end
@@ -1,35 +0,0 @@
1
- require "spec_helper"
2
- require "bunny/concurrent/atomic_fixnum"
3
-
4
- describe Bunny::Concurrent::AtomicFixnum do
5
- it "allows retrieving the current value" do
6
- af = described_class.new(0)
7
-
8
- expect(af.get).to eq 0
9
- expect(af).to eq 0
10
- end
11
-
12
- it "can be updated" do
13
- af = described_class.new(0)
14
-
15
- expect(af.get).to eq 0
16
- Thread.new do
17
- af.set(10)
18
- end
19
- sleep 0.6
20
- expect(af.get).to eq 10
21
- end
22
-
23
- it "can be incremented" do
24
- af = described_class.new(0)
25
-
26
- expect(af.get).to eq 0
27
- 10.times do
28
- Thread.new do
29
- af.increment
30
- end
31
- end
32
- sleep 0.6
33
- expect(af.get).to eq 10
34
- end
35
- end
@@ -1,82 +0,0 @@
1
- require "spec_helper"
2
- require "bunny/concurrent/condition"
3
-
4
- describe Bunny::Concurrent::Condition do
5
-
6
- describe "#wait" do
7
- 50.times do |i|
8
- it "blocks current thread until notified (take #{i})" do
9
- condition = described_class.new
10
- xs = []
11
-
12
- t = Thread.new do
13
- xs << :notified
14
-
15
- sleep 0.2
16
- condition.notify
17
- end
18
- t.abort_on_exception = true
19
-
20
- condition.wait
21
- expect(xs).to eq [:notified]
22
- end
23
- end
24
- end
25
-
26
- describe "#notify" do
27
- 50.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 = []
32
-
33
- t1 = Thread.new do
34
- condition.wait
35
- mutex.synchronize { xs << :notified1 }
36
- end
37
- t1.abort_on_exception = true
38
-
39
- t2 = Thread.new do
40
- condition.wait
41
- mutex.synchronize { xs << :notified2 }
42
- end
43
- t2.abort_on_exception = true
44
-
45
- sleep 0.2
46
- condition.notify
47
- sleep 0.5
48
- expect(xs).to satisfy { |ys| ys.size == 1 && (ys.include?(:notified1) || ys.include?(:notified2)) }
49
- end
50
- end
51
- end
52
-
53
- describe "#notify_all" do
54
- let(:n) { 30 }
55
-
56
- 50.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 = []
61
-
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
68
- end
69
-
70
- sleep 0.5
71
- condition.notify_all
72
- sleep 0.5
73
-
74
- n.times do |i|
75
- item = "notified#{i + 1}".to_sym
76
-
77
- expect(@xs).to include item
78
- end
79
- end
80
- end
81
- end
82
- end
@@ -1,35 +0,0 @@
1
- require "spec_helper"
2
-
3
- if defined?(JRUBY_VERSION)
4
- require "bunny/concurrent/linked_continuation_queue"
5
-
6
- describe Bunny::Concurrent::LinkedContinuationQueue do
7
- describe "#poll with a timeout that is never reached" do
8
- it "blocks until the value is available, then returns it" do
9
- # force subject evaluation
10
- cq = subject
11
- t = Thread.new do
12
- cq.push(10)
13
- end
14
- t.abort_on_exception = true
15
-
16
- v = subject.poll(500)
17
- expect(v).to eq 10
18
- end
19
- end
20
-
21
- describe "#poll with a timeout that is reached" do
22
- it "raises an exception" do
23
- # force subject evaluation
24
- cq = subject
25
- t = Thread.new do
26
- sleep 1.5
27
- cq.push(10)
28
- end
29
- t.abort_on_exception = true
30
-
31
- expect { subject.poll(500) }.to raise_error(::Timeout::Error)
32
- end
33
- end
34
- end
35
- end
@@ -1,73 +0,0 @@
1
- require "spec_helper"
2
- require "bunny/concurrent/synchronized_sorted_set"
3
-
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
- expect(s.length).to eq 0
10
-
11
- s << 1
12
- expect(s.length).to eq 1
13
- s << 1
14
- expect(s.length).to eq 1
15
- s << 2
16
- expect(s.length).to eq 2
17
- s << 3
18
- expect(s.length).to eq 3
19
- s << 4
20
- expect(s.length).to eq 4
21
- s << 4
22
- s << 4
23
- s << 4
24
- expect(s.length).to eq 4
25
- s << 5
26
- expect(s.length).to eq 5
27
- s << 5
28
- s << 5
29
- s << 5
30
- expect(s.length).to eq 5
31
- s << 6
32
- expect(s.length).to eq 6
33
- s << 7
34
- expect(s.length).to eq 7
35
- s << 8
36
- expect(s.length).to eq 8
37
- s.delete 8
38
- expect(s.length).to eq 7
39
- s.delete_if { |i| i == 1 }
40
- expect(s.length).to eq 6
41
- end
42
- it "synchronizes common operations needed by Bunny (take #{i})" do
43
- s = described_class.new
44
- expect(s.length).to eq 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
68
-
69
- expect(s.length).to eq 6
70
- end
71
- end
72
- end
73
- end
@@ -1,39 +0,0 @@
1
- require 'bunny/channel'
2
- require 'bunny/exchange'
3
-
4
- module Bunny
5
- describe Exchange do
6
- context "recovery" do
7
- it "recovers exchange bindings, unless already unbound" do
8
- ch = instance_double(Bunny::Channel,
9
- exchange_declare: nil,
10
- register_exchange: nil)
11
- src1 = Exchange.new(ch, "direct", "src1")
12
- src2 = Exchange.new(ch, "direct", "src2")
13
- src3 = Exchange.new(ch, "direct", "src3")
14
- dst = Exchange.new(ch, "direct", "dst")
15
-
16
- original_binds_count = 5
17
- expected_rebinds_count = 3
18
- expected_total_binds = original_binds_count + expected_rebinds_count
19
- allow(ch).to receive(:exchange_bind).exactly(expected_total_binds).times
20
-
21
- dst.bind(src1, routing_key: "abc")
22
- dst.bind(src2, routing_key: "def")
23
- dst.bind(src2, routing_key: "ghi")
24
- dst.bind(src3, routing_key: "jkl")
25
- dst.bind(src3, routing_key: "jkl", arguments: {"key" => "value"})
26
-
27
- allow(ch).to receive(:exchange_unbind).twice
28
- dst.unbind(src2, routing_key: "def")
29
- dst.unbind(src3, routing_key: "jkl", arguments: {"key" => "value"})
30
-
31
- expect(ch).to receive(:exchange_bind).with(src1, dst, routing_key: "abc")
32
- expect(ch).to receive(:exchange_bind).with(src2, dst, routing_key: "ghi")
33
- expect(ch).to receive(:exchange_bind).with(src3, dst, routing_key: "jkl")
34
-
35
- dst.recover_from_network_failure
36
- end
37
- end
38
- end
39
- end
@@ -1,28 +0,0 @@
1
- require "spec_helper"
2
-
3
- require "bunny/concurrent/atomic_fixnum"
4
- require "bunny/versioned_delivery_tag"
5
-
6
- describe Bunny::VersionedDeliveryTag, "#stale?" do
7
- subject { described_class.new(2, 1) }
8
-
9
- context "when delivery tag version < provided version" do
10
- it "returns true" do
11
- expect(subject.stale?(2)).to eq true
12
- end
13
- end
14
-
15
- context "when delivery tag version = provided version" do
16
- it "returns false" do
17
- expect(subject.stale?(1)).to eq false
18
- end
19
- end
20
-
21
- context "when delivery tag version > provided version" do
22
- it "returns true" do
23
- # this scenario is unrealistic but we still can
24
- # unit test it. MK.
25
- expect(subject.stale?(0)).to eq false
26
- end
27
- end
28
- end