bunny 1.0.7 → 2.24.0
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.
- checksums.yaml +5 -5
- data/README.md +92 -87
- data/lib/amq/protocol/extensions.rb +2 -0
- data/lib/bunny/authentication/credentials_encoder.rb +2 -0
- data/lib/bunny/authentication/external_mechanism_encoder.rb +2 -0
- data/lib/bunny/authentication/plain_mechanism_encoder.rb +2 -0
- data/lib/bunny/channel.rb +485 -186
- data/lib/bunny/channel_id_allocator.rb +8 -4
- data/lib/bunny/concurrent/atomic_fixnum.rb +2 -0
- data/lib/bunny/concurrent/condition.rb +2 -0
- data/lib/bunny/concurrent/continuation_queue.rb +37 -13
- data/lib/bunny/concurrent/synchronized_sorted_set.rb +2 -0
- data/lib/bunny/consumer.rb +20 -13
- data/lib/bunny/consumer_tag_generator.rb +6 -2
- data/lib/bunny/consumer_work_pool.rb +37 -7
- data/lib/bunny/cruby/socket.rb +51 -22
- data/lib/bunny/cruby/ssl_socket.rb +68 -5
- data/lib/bunny/delivery_info.rb +3 -1
- data/lib/bunny/exceptions.rb +27 -4
- data/lib/bunny/exchange.rb +35 -29
- data/lib/bunny/framing.rb +2 -0
- data/lib/bunny/get_response.rb +85 -0
- data/lib/bunny/heartbeat_sender.rb +9 -6
- data/lib/bunny/message_properties.rb +2 -0
- data/lib/bunny/queue.rb +89 -41
- data/lib/bunny/reader_loop.rb +72 -28
- data/lib/bunny/return_info.rb +2 -0
- data/lib/bunny/session.rb +621 -225
- data/lib/bunny/socket.rb +7 -12
- data/lib/bunny/ssl_socket.rb +7 -12
- data/lib/bunny/test_kit.rb +15 -0
- data/lib/bunny/timeout.rb +3 -12
- data/lib/bunny/timestamp.rb +24 -0
- data/lib/bunny/transport.rb +223 -98
- data/lib/bunny/version.rb +2 -1
- data/lib/bunny/versioned_delivery_tag.rb +2 -0
- data/lib/bunny.rb +54 -8
- metadata +38 -224
- data/.gitignore +0 -22
- data/.rspec +0 -3
- data/.ruby-version +0 -1
- data/.travis.yml +0 -23
- data/.yardopts +0 -8
- data/ChangeLog.md +0 -1092
- data/Gemfile +0 -54
- data/LICENSE +0 -21
- data/benchmarks/basic_publish/with_128K_messages.rb +0 -35
- data/benchmarks/basic_publish/with_1k_messages.rb +0 -35
- data/benchmarks/basic_publish/with_4K_messages.rb +0 -35
- data/benchmarks/basic_publish/with_64K_messages.rb +0 -35
- data/benchmarks/channel_open.rb +0 -28
- data/benchmarks/mutex_and_monitor.rb +0 -42
- data/benchmarks/queue_declare.rb +0 -29
- data/benchmarks/queue_declare_and_bind.rb +0 -29
- data/benchmarks/queue_declare_bind_and_delete.rb +0 -29
- data/benchmarks/synchronized_sorted_set.rb +0 -53
- data/benchmarks/write_vs_write_nonblock.rb +0 -49
- data/bin/ci/before_build.sh +0 -31
- data/bunny.gemspec +0 -40
- data/examples/connection/authentication_failure.rb +0 -16
- data/examples/connection/automatic_recovery_with_basic_get.rb +0 -40
- data/examples/connection/automatic_recovery_with_client_named_queues.rb +0 -36
- data/examples/connection/automatic_recovery_with_multiple_consumers.rb +0 -46
- data/examples/connection/automatic_recovery_with_server_named_queues.rb +0 -35
- data/examples/connection/channel_level_exception.rb +0 -35
- data/examples/connection/disabled_automatic_recovery.rb +0 -34
- data/examples/connection/heartbeat.rb +0 -17
- data/examples/connection/manually_reconnecting_consumer.rb +0 -23
- data/examples/connection/manually_reconnecting_publisher.rb +0 -28
- data/examples/connection/unknown_host.rb +0 -16
- data/examples/guides/exchanges/direct_exchange_routing.rb +0 -36
- data/examples/guides/exchanges/fanout_exchange_routing.rb +0 -28
- data/examples/guides/exchanges/headers_exchange_routing.rb +0 -31
- data/examples/guides/exchanges/mandatory_messages.rb +0 -30
- data/examples/guides/extensions/alternate_exchange.rb +0 -28
- data/examples/guides/extensions/basic_nack.rb +0 -33
- data/examples/guides/extensions/connection_blocked.rb +0 -35
- data/examples/guides/extensions/consumer_cancellation_notification.rb +0 -39
- data/examples/guides/extensions/dead_letter_exchange.rb +0 -32
- data/examples/guides/extensions/exchange_to_exchange_bindings.rb +0 -29
- data/examples/guides/extensions/per_message_ttl.rb +0 -36
- data/examples/guides/extensions/per_queue_message_ttl.rb +0 -36
- data/examples/guides/extensions/publisher_confirms.rb +0 -28
- data/examples/guides/extensions/queue_lease.rb +0 -26
- data/examples/guides/extensions/sender_selected_distribution.rb +0 -32
- data/examples/guides/getting_started/blabbr.rb +0 -27
- data/examples/guides/getting_started/hello_world.rb +0 -20
- data/examples/guides/getting_started/weathr.rb +0 -47
- data/examples/guides/queues/one_off_consumer.rb +0 -23
- data/examples/guides/queues/redeliveries.rb +0 -79
- data/lib/bunny/compatibility.rb +0 -24
- data/lib/bunny/concurrent/linked_continuation_queue.rb +0 -61
- data/lib/bunny/jruby/socket.rb +0 -40
- data/lib/bunny/jruby/ssl_socket.rb +0 -53
- data/lib/bunny/system_timer.rb +0 -20
- data/profiling/basic_publish/with_4K_messages.rb +0 -33
- data/repl +0 -3
- data/spec/compatibility/queue_declare_spec.rb +0 -44
- data/spec/compatibility/queue_declare_with_default_channel_spec.rb +0 -33
- data/spec/higher_level_api/integration/basic_ack_spec.rb +0 -71
- data/spec/higher_level_api/integration/basic_cancel_spec.rb +0 -76
- data/spec/higher_level_api/integration/basic_consume_spec.rb +0 -225
- data/spec/higher_level_api/integration/basic_consume_with_objects_spec.rb +0 -54
- data/spec/higher_level_api/integration/basic_get_spec.rb +0 -48
- data/spec/higher_level_api/integration/basic_nack_spec.rb +0 -79
- data/spec/higher_level_api/integration/basic_publish_spec.rb +0 -89
- data/spec/higher_level_api/integration/basic_qos_spec.rb +0 -29
- data/spec/higher_level_api/integration/basic_recover_spec.rb +0 -18
- data/spec/higher_level_api/integration/basic_reject_spec.rb +0 -74
- data/spec/higher_level_api/integration/basic_return_spec.rb +0 -33
- data/spec/higher_level_api/integration/channel_close_spec.rb +0 -25
- data/spec/higher_level_api/integration/channel_flow_spec.rb +0 -21
- data/spec/higher_level_api/integration/channel_open_spec.rb +0 -57
- data/spec/higher_level_api/integration/confirm_select_spec.rb +0 -19
- data/spec/higher_level_api/integration/connection_spec.rb +0 -400
- data/spec/higher_level_api/integration/connection_stop_spec.rb +0 -26
- data/spec/higher_level_api/integration/consistent_hash_exchange_spec.rb +0 -50
- data/spec/higher_level_api/integration/consumer_cancellation_notification_spec.rb +0 -128
- data/spec/higher_level_api/integration/dead_lettering_spec.rb +0 -52
- data/spec/higher_level_api/integration/exchange_bind_spec.rb +0 -31
- data/spec/higher_level_api/integration/exchange_declare_spec.rb +0 -204
- data/spec/higher_level_api/integration/exchange_delete_spec.rb +0 -105
- data/spec/higher_level_api/integration/exchange_unbind_spec.rb +0 -40
- data/spec/higher_level_api/integration/exclusive_queue_spec.rb +0 -28
- data/spec/higher_level_api/integration/heartbeat_spec.rb +0 -31
- data/spec/higher_level_api/integration/merry_go_round_spec.rb +0 -85
- data/spec/higher_level_api/integration/message_properties_access_spec.rb +0 -95
- data/spec/higher_level_api/integration/predeclared_exchanges_spec.rb +0 -24
- data/spec/higher_level_api/integration/publisher_confirms_spec.rb +0 -77
- data/spec/higher_level_api/integration/publishing_edge_cases_spec.rb +0 -65
- data/spec/higher_level_api/integration/queue_bind_spec.rb +0 -109
- data/spec/higher_level_api/integration/queue_declare_spec.rb +0 -190
- data/spec/higher_level_api/integration/queue_delete_spec.rb +0 -41
- data/spec/higher_level_api/integration/queue_purge_spec.rb +0 -30
- data/spec/higher_level_api/integration/queue_unbind_spec.rb +0 -54
- data/spec/higher_level_api/integration/read_only_consumer_spec.rb +0 -60
- data/spec/higher_level_api/integration/sender_selected_distribution_spec.rb +0 -36
- data/spec/higher_level_api/integration/tls_connection_spec.rb +0 -127
- data/spec/higher_level_api/integration/tx_commit_spec.rb +0 -21
- data/spec/higher_level_api/integration/tx_rollback_spec.rb +0 -21
- data/spec/higher_level_api/integration/with_channel_spec.rb +0 -25
- data/spec/issues/issue100_spec.rb +0 -42
- data/spec/issues/issue141_spec.rb +0 -44
- data/spec/issues/issue78_spec.rb +0 -75
- data/spec/issues/issue83_spec.rb +0 -31
- data/spec/issues/issue97_attachment.json +0 -1
- data/spec/issues/issue97_spec.rb +0 -176
- data/spec/lower_level_api/integration/basic_cancel_spec.rb +0 -69
- data/spec/lower_level_api/integration/basic_consume_spec.rb +0 -100
- data/spec/spec_helper.rb +0 -64
- data/spec/stress/channel_open_stress_spec.rb +0 -51
- data/spec/stress/channel_open_stress_with_single_threaded_connection_spec.rb +0 -28
- data/spec/stress/concurrent_consumers_stress_spec.rb +0 -69
- data/spec/stress/concurrent_publishers_stress_spec.rb +0 -57
- data/spec/stress/connection_open_close_spec.rb +0 -40
- data/spec/stress/long_running_consumer_spec.rb +0 -83
- data/spec/tls/cacert.pem +0 -18
- data/spec/tls/client_cert.pem +0 -18
- data/spec/tls/client_key.pem +0 -27
- data/spec/tls/server_cert.pem +0 -18
- data/spec/tls/server_key.pem +0 -27
- data/spec/unit/bunny_spec.rb +0 -15
- data/spec/unit/concurrent/atomic_fixnum_spec.rb +0 -35
- data/spec/unit/concurrent/condition_spec.rb +0 -82
- data/spec/unit/concurrent/linked_continuation_queue_spec.rb +0 -35
- data/spec/unit/concurrent/synchronized_sorted_set_spec.rb +0 -73
- data/spec/unit/system_timer_spec.rb +0 -10
- data/spec/unit/version_delivery_tag_spec.rb +0 -28
@@ -1,26 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: utf-8
|
3
|
-
|
4
|
-
require "rubygems"
|
5
|
-
require "bunny"
|
6
|
-
|
7
|
-
puts "=> Demonstrating queue TTL (queue leases)"
|
8
|
-
puts
|
9
|
-
|
10
|
-
conn = Bunny.new
|
11
|
-
conn.start
|
12
|
-
|
13
|
-
ch = conn.create_channel
|
14
|
-
q = ch.queue("", :exclusive => true, :arguments => {"x-expires" => 300})
|
15
|
-
|
16
|
-
sleep 0.4
|
17
|
-
begin
|
18
|
-
# this will raise because the queue is already deleted
|
19
|
-
q.message_count
|
20
|
-
rescue Bunny::NotFound => nfe
|
21
|
-
puts "Got a 404 response: the queue has already been removed"
|
22
|
-
end
|
23
|
-
|
24
|
-
sleep 0.7
|
25
|
-
puts "Closing..."
|
26
|
-
conn.close
|
@@ -1,32 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: utf-8
|
3
|
-
|
4
|
-
require "rubygems"
|
5
|
-
require "bunny"
|
6
|
-
|
7
|
-
puts "=> Demonstrating sender-selected distribution"
|
8
|
-
puts
|
9
|
-
|
10
|
-
conn = Bunny.new
|
11
|
-
conn.start
|
12
|
-
|
13
|
-
ch = conn.create_channel
|
14
|
-
x = ch.direct("bunny.examples.ssd.exchange")
|
15
|
-
q1 = ch.queue("", :exclusive => true).bind(x, :routing_key => "one")
|
16
|
-
q2 = ch.queue("", :exclusive => true).bind(x, :routing_key => "two")
|
17
|
-
q3 = ch.queue("", :exclusive => true).bind(x, :routing_key => "three")
|
18
|
-
q4 = ch.queue("", :exclusive => true).bind(x, :routing_key => "four")
|
19
|
-
|
20
|
-
10.times do |i|
|
21
|
-
x.publish("Message #{i}", :routing_key => "one", :headers => {"CC" => ["two", "three"]})
|
22
|
-
end
|
23
|
-
|
24
|
-
sleep 0.2
|
25
|
-
puts "Queue #{q1.name} now has #{q1.message_count} messages in it"
|
26
|
-
puts "Queue #{q2.name} now has #{q2.message_count} messages in it"
|
27
|
-
puts "Queue #{q3.name} now has #{q3.message_count} messages in it"
|
28
|
-
puts "Queue #{q4.name} now has #{q4.message_count} messages in it"
|
29
|
-
|
30
|
-
sleep 0.7
|
31
|
-
puts "Closing..."
|
32
|
-
conn.close
|
@@ -1,27 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: utf-8
|
3
|
-
|
4
|
-
require "rubygems"
|
5
|
-
require "bunny"
|
6
|
-
|
7
|
-
conn = Bunny.new
|
8
|
-
conn.start
|
9
|
-
|
10
|
-
ch = conn.create_channel
|
11
|
-
x = ch.fanout("nba.scores")
|
12
|
-
|
13
|
-
ch.queue("joe", :auto_delete => true).bind(x).subscribe do |delivery_info, properties, payload|
|
14
|
-
puts "#{payload} => joe"
|
15
|
-
end
|
16
|
-
|
17
|
-
ch.queue("aaron", :auto_delete => true).bind(x).subscribe do |delivery_info, properties, payload|
|
18
|
-
puts "#{payload} => aaron"
|
19
|
-
end
|
20
|
-
|
21
|
-
ch.queue("bob", :auto_delete => true).bind(x).subscribe do |delivery_info, properties, payload|
|
22
|
-
puts "#{payload} => bob"
|
23
|
-
end
|
24
|
-
|
25
|
-
x.publish("BOS 101, NYK 89").publish("ORL 85, ALT 88")
|
26
|
-
|
27
|
-
conn.close
|
@@ -1,20 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: utf-8
|
3
|
-
|
4
|
-
require "rubygems"
|
5
|
-
require "bunny"
|
6
|
-
|
7
|
-
conn = Bunny.new
|
8
|
-
conn.start
|
9
|
-
|
10
|
-
ch = conn.create_channel
|
11
|
-
q = ch.queue("bunny.examples.hello_world", :auto_delete => true)
|
12
|
-
|
13
|
-
q.subscribe do |delivery_info, properties, payload|
|
14
|
-
puts "Received #{payload}"
|
15
|
-
end
|
16
|
-
|
17
|
-
q.publish("Hello!", :routing_key => q.name)
|
18
|
-
|
19
|
-
sleep 1.0
|
20
|
-
conn.close
|
@@ -1,47 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: utf-8
|
3
|
-
|
4
|
-
require "rubygems"
|
5
|
-
require "bunny"
|
6
|
-
|
7
|
-
connection = Bunny.new
|
8
|
-
connection.start
|
9
|
-
|
10
|
-
channel = connection.create_channel
|
11
|
-
# topic exchange name can be any string
|
12
|
-
exchange = channel.topic("weathr", :auto_delete => true)
|
13
|
-
|
14
|
-
# Subscribers.
|
15
|
-
channel.queue("", :exclusive => true).bind(exchange, :routing_key => "americas.north.#").subscribe do |delivery_info, properties, payload|
|
16
|
-
puts "An update for North America: #{payload}, routing key is #{delivery_info.routing_key}"
|
17
|
-
end
|
18
|
-
channel.queue("americas.south").bind(exchange, :routing_key => "americas.south.#").subscribe do |delivery_info, properties, payload|
|
19
|
-
puts "An update for South America: #{payload}, routing key is #{delivery_info.routing_key}"
|
20
|
-
end
|
21
|
-
channel.queue("us.california").bind(exchange, :routing_key => "americas.north.us.ca.*").subscribe do |delivery_info, properties, payload|
|
22
|
-
puts "An update for US/California: #{payload}, routing key is #{delivery_info.routing_key}"
|
23
|
-
end
|
24
|
-
channel.queue("us.tx.austin").bind(exchange, :routing_key => "#.tx.austin").subscribe do |delivery_info, properties, payload|
|
25
|
-
puts "An update for Austin, TX: #{payload}, routing key is #{delivery_info.routing_key}"
|
26
|
-
end
|
27
|
-
channel.queue("it.rome").bind(exchange, :routing_key => "europe.italy.rome").subscribe do |delivery_info, properties, payload|
|
28
|
-
puts "An update for Rome, Italy: #{payload}, routing key is #{delivery_info.routing_key}"
|
29
|
-
end
|
30
|
-
channel.queue("asia.hk").bind(exchange, :routing_key => "asia.southeast.hk.#").subscribe do |delivery_info, properties, payload|
|
31
|
-
puts "An update for Hong Kong: #{payload}, routing key is #{delivery_info.routing_key}"
|
32
|
-
end
|
33
|
-
|
34
|
-
exchange.publish("San Diego update", :routing_key => "americas.north.us.ca.sandiego").
|
35
|
-
publish("Berkeley update", :routing_key => "americas.north.us.ca.berkeley").
|
36
|
-
publish("San Francisco update", :routing_key => "americas.north.us.ca.sanfrancisco").
|
37
|
-
publish("New York update", :routing_key => "americas.north.us.ny.newyork").
|
38
|
-
publish("São Paolo update", :routing_key => "americas.south.brazil.saopaolo").
|
39
|
-
publish("Hong Kong update", :routing_key => "asia.southeast.hk.hongkong").
|
40
|
-
publish("Kyoto update", :routing_key => "asia.southeast.japan.kyoto").
|
41
|
-
publish("Shanghai update", :routing_key => "asia.southeast.prc.shanghai").
|
42
|
-
publish("Rome update", :routing_key => "europe.italy.roma").
|
43
|
-
publish("Paris update", :routing_key => "europe.france.paris")
|
44
|
-
|
45
|
-
sleep 1.0
|
46
|
-
|
47
|
-
connection.close
|
@@ -1,23 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: utf-8
|
3
|
-
|
4
|
-
require "rubygems"
|
5
|
-
require "bunny"
|
6
|
-
|
7
|
-
conn = Bunny.new
|
8
|
-
conn.start
|
9
|
-
|
10
|
-
ch = conn.create_channel
|
11
|
-
q = ch.queue("bunny.examples.hello_world", :auto_delete => true)
|
12
|
-
|
13
|
-
q.publish("Hello!", :routing_key => q.name)
|
14
|
-
|
15
|
-
# demonstrates a blocking consumer that needs to cancel itself
|
16
|
-
# in the message handler
|
17
|
-
q.subscribe(:block => true) do |delivery_info, properties, payload|
|
18
|
-
puts "Received #{payload}, cancelling"
|
19
|
-
delivery_info.consumer.cancel
|
20
|
-
end
|
21
|
-
|
22
|
-
sleep 1.0
|
23
|
-
conn.close
|
@@ -1,79 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: utf-8
|
3
|
-
|
4
|
-
require "rubygems"
|
5
|
-
require "bunny"
|
6
|
-
|
7
|
-
puts "=> Subscribing for messages using explicit acknowledgements model"
|
8
|
-
puts
|
9
|
-
|
10
|
-
connection1 = Bunny.new
|
11
|
-
connection1.start
|
12
|
-
|
13
|
-
connection2 = Bunny.new
|
14
|
-
connection2.start
|
15
|
-
|
16
|
-
connection3 = Bunny.new
|
17
|
-
connection3.start
|
18
|
-
|
19
|
-
ch1 = connection1.create_channel
|
20
|
-
ch1.prefetch(1)
|
21
|
-
|
22
|
-
ch2 = connection2.create_channel
|
23
|
-
ch2.prefetch(1)
|
24
|
-
|
25
|
-
ch3 = connection3.create_channel
|
26
|
-
ch3.prefetch(1)
|
27
|
-
|
28
|
-
x = ch3.direct("amq.direct")
|
29
|
-
q1 = ch1.queue("bunny.examples.acknowledgements.explicit", :auto_delete => false)
|
30
|
-
q1.purge
|
31
|
-
|
32
|
-
q1.bind(x).subscribe(:ack => true, :block => false) do |delivery_info, properties, payload|
|
33
|
-
# do some work
|
34
|
-
sleep(0.2)
|
35
|
-
|
36
|
-
# acknowledge some messages, they will be removed from the queue
|
37
|
-
if rand > 0.5
|
38
|
-
# FYI: there is a shortcut, Bunny::Channel.ack
|
39
|
-
ch1.acknowledge(delivery_info.delivery_tag, false)
|
40
|
-
puts "[consumer1] Got message ##{properties.headers['i']}, redelivered?: #{delivery_info.redelivered?}, ack-ed"
|
41
|
-
else
|
42
|
-
# some messages are not ack-ed and will remain in the queue for redelivery
|
43
|
-
# when app #1 connection is closed (either properly or due to a crash)
|
44
|
-
puts "[consumer1] Got message ##{properties.headers['i']}, SKIPPED"
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
q2 = ch2.queue("bunny.examples.acknowledgements.explicit", :auto_delete => false)
|
49
|
-
q2.bind(x).subscribe(:ack => true, :block => false) do |delivery_info, properties, payload|
|
50
|
-
# do some work
|
51
|
-
sleep(0.2)
|
52
|
-
|
53
|
-
ch2.acknowledge(delivery_info.delivery_tag, false)
|
54
|
-
puts "[consumer2] Got message ##{properties.headers['i']}, redelivered?: #{delivery_info.redelivered?}, ack-ed"
|
55
|
-
end
|
56
|
-
|
57
|
-
t1 = Thread.new do
|
58
|
-
i = 0
|
59
|
-
loop do
|
60
|
-
sleep 0.5
|
61
|
-
|
62
|
-
x.publish("Message ##{i}", :headers => { :i => i })
|
63
|
-
i += 1
|
64
|
-
end
|
65
|
-
end
|
66
|
-
t1.abort_on_exception = true
|
67
|
-
|
68
|
-
t2 = Thread.new do
|
69
|
-
sleep 4.0
|
70
|
-
|
71
|
-
connection1.close
|
72
|
-
puts "----- Connection 1 is now closed (we pretend that it has crashed) -----"
|
73
|
-
end
|
74
|
-
t2.abort_on_exception = true
|
75
|
-
|
76
|
-
|
77
|
-
sleep 7.0
|
78
|
-
connection2.close
|
79
|
-
connection3.close
|
data/lib/bunny/compatibility.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
module Bunny
|
2
|
-
# Helper methods necessary to stay mostly backwards-compatible with legacy (0.7.x, 0.8.x) Bunny
|
3
|
-
# releases that hide channels completely from the API.
|
4
|
-
#
|
5
|
-
# @private
|
6
|
-
module Compatibility
|
7
|
-
|
8
|
-
#
|
9
|
-
# API
|
10
|
-
#
|
11
|
-
|
12
|
-
# @private
|
13
|
-
def channel_from(channel_or_connection)
|
14
|
-
# Bunny 0.8.x and earlier completely hide channels from the API. So, queues and exchanges are
|
15
|
-
# instantiated with a "Bunny object", which is a session. This function coerces two types of input to a
|
16
|
-
# channel.
|
17
|
-
if channel_or_connection.is_a?(Bunny::Session)
|
18
|
-
channel_or_connection.default_channel
|
19
|
-
else
|
20
|
-
channel_or_connection
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
if !defined?(JRUBY_VERSION)
|
2
|
-
raise "Bunny::Concurrent::LinkedContinuationQueue can only be used on JRuby!"
|
3
|
-
end
|
4
|
-
|
5
|
-
require "java"
|
6
|
-
|
7
|
-
java_import java.util.concurrent.LinkedBlockingQueue
|
8
|
-
java_import java.util.concurrent.TimeUnit
|
9
|
-
|
10
|
-
module Bunny
|
11
|
-
module Concurrent
|
12
|
-
# Continuation queue implementation for JRuby.
|
13
|
-
#
|
14
|
-
# On JRuby, we'd rather use reliable and heavily battle tested j.u.c.
|
15
|
-
# primitives with well described semantics than informally specified, clumsy
|
16
|
-
# and limited Ruby standard library parts.
|
17
|
-
#
|
18
|
-
# This is an implementation of the continuation queue on top of the linked blocking
|
19
|
-
# queue in j.u.c.
|
20
|
-
#
|
21
|
-
# Compared to the Ruby standard library Queue, there is one limitation: you cannot
|
22
|
-
# push a nil on the queue, it will fail with a null pointer exception.
|
23
|
-
# @private
|
24
|
-
class LinkedContinuationQueue
|
25
|
-
def initialize(*args, &block)
|
26
|
-
@q = LinkedBlockingQueue.new
|
27
|
-
end
|
28
|
-
|
29
|
-
def push(el, timeout_in_ms = nil)
|
30
|
-
if timeout_in_ms
|
31
|
-
@q.offer(el, timeout_in_ms, TimeUnit::MILLISECONDS)
|
32
|
-
else
|
33
|
-
@q.offer(el)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
alias << push
|
37
|
-
|
38
|
-
def pop
|
39
|
-
@q.take
|
40
|
-
end
|
41
|
-
|
42
|
-
def poll(timeout_in_ms = nil)
|
43
|
-
if timeout_in_ms
|
44
|
-
v = @q.poll(timeout_in_ms, TimeUnit::MILLISECONDS)
|
45
|
-
raise ::Timeout::Error.new("operation did not finish in #{timeout_in_ms} ms") if v.nil?
|
46
|
-
v
|
47
|
-
else
|
48
|
-
@q.poll
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def clear
|
53
|
-
@q.clear
|
54
|
-
end
|
55
|
-
|
56
|
-
def method_missing(selector, *args, &block)
|
57
|
-
@q.__send__(selector, *args, &block)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
data/lib/bunny/jruby/socket.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
require "bunny/cruby/socket"
|
2
|
-
|
3
|
-
module Bunny
|
4
|
-
module JRuby
|
5
|
-
# TCP socket extension that uses Socket#readpartial to avoid excessive CPU
|
6
|
-
# burn after some time. See issue #165.
|
7
|
-
# @private
|
8
|
-
class Socket < Bunny::Socket
|
9
|
-
|
10
|
-
# Reads given number of bytes with an optional timeout
|
11
|
-
#
|
12
|
-
# @param [Integer] count How many bytes to read
|
13
|
-
# @param [Integer] timeout Timeout
|
14
|
-
#
|
15
|
-
# @return [String] Data read from the socket
|
16
|
-
# @api public
|
17
|
-
def read_fully(count, timeout = nil)
|
18
|
-
return nil if @__bunny_socket_eof_flag__
|
19
|
-
|
20
|
-
value = ''
|
21
|
-
begin
|
22
|
-
loop do
|
23
|
-
value << readpartial(count - value.bytesize)
|
24
|
-
break if value.bytesize >= count
|
25
|
-
end
|
26
|
-
rescue EOFError
|
27
|
-
# @eof will break Rubinius' TCPSocket implementation. MK.
|
28
|
-
@__bunny_socket_eof_flag__ = true
|
29
|
-
rescue *READ_RETRY_EXCEPTION_CLASSES
|
30
|
-
if IO.select([self], nil, nil, timeout)
|
31
|
-
retry
|
32
|
-
else
|
33
|
-
raise Timeout::Error, "IO timeout when reading #{count} bytes"
|
34
|
-
end
|
35
|
-
end
|
36
|
-
value
|
37
|
-
end # read_fully
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
module Bunny
|
2
|
-
module JRuby
|
3
|
-
begin
|
4
|
-
require "bunny/cruby/ssl_socket"
|
5
|
-
require "openssl"
|
6
|
-
|
7
|
-
# TLS-enabled TCP socket that implements convenience
|
8
|
-
# methods found in Bunny::Socket.
|
9
|
-
class SSLSocket < Bunny::SSLSocket
|
10
|
-
|
11
|
-
# Reads given number of bytes with an optional timeout
|
12
|
-
#
|
13
|
-
# @param [Integer] count How many bytes to read
|
14
|
-
# @param [Integer] timeout Timeout
|
15
|
-
#
|
16
|
-
# @return [String] Data read from the socket
|
17
|
-
# @api public
|
18
|
-
def read_fully(count, timeout = nil)
|
19
|
-
return nil if @__bunny_socket_eof_flag__
|
20
|
-
|
21
|
-
value = ''
|
22
|
-
begin
|
23
|
-
loop do
|
24
|
-
value << read_nonblock(count - value.bytesize)
|
25
|
-
break if value.bytesize >= count
|
26
|
-
end
|
27
|
-
rescue EOFError => e
|
28
|
-
@__bunny_socket_eof_flag__ = true
|
29
|
-
rescue OpenSSL::SSL::SSLError => e
|
30
|
-
if e.message == "read would block"
|
31
|
-
if IO.select([self], nil, nil, timeout)
|
32
|
-
retry
|
33
|
-
else
|
34
|
-
raise Timeout::Error, "IO timeout when reading #{count} bytes"
|
35
|
-
end
|
36
|
-
else
|
37
|
-
raise e
|
38
|
-
end
|
39
|
-
rescue *READ_RETRY_EXCEPTION_CLASSES => e
|
40
|
-
if IO.select([self], nil, nil, timeout)
|
41
|
-
retry
|
42
|
-
else
|
43
|
-
raise Timeout::Error, "IO timeout when reading #{count} bytes"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
value
|
47
|
-
end
|
48
|
-
end
|
49
|
-
rescue LoadError => le
|
50
|
-
puts "Could not load OpenSSL"
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
data/lib/bunny/system_timer.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8; mode: ruby -*-
|
2
|
-
|
3
|
-
require "system_timer"
|
4
|
-
|
5
|
-
module Bunny
|
6
|
-
# Used for Ruby before 1.9
|
7
|
-
class SystemTimer
|
8
|
-
# Executes a block of code, raising if the execution does not finish
|
9
|
-
# in the alloted period of time, in seconds.
|
10
|
-
def self.timeout(seconds, exception = nil)
|
11
|
-
if seconds
|
12
|
-
::SystemTimer.timeout_after(seconds, exception) do
|
13
|
-
yield
|
14
|
-
end
|
15
|
-
else
|
16
|
-
yield
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end # SystemTimer
|
20
|
-
end # Bunny
|
@@ -1,33 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: utf-8
|
3
|
-
|
4
|
-
require "rubygems"
|
5
|
-
require "bunny"
|
6
|
-
require "ruby-prof"
|
7
|
-
|
8
|
-
conn = Bunny.new
|
9
|
-
conn.start
|
10
|
-
|
11
|
-
puts
|
12
|
-
puts "-" * 80
|
13
|
-
puts "Benchmarking on #{RUBY_DESCRIPTION}"
|
14
|
-
|
15
|
-
n = 50_000
|
16
|
-
ch = conn.create_channel
|
17
|
-
x = ch.default_exchange
|
18
|
-
s = "z" * 4096
|
19
|
-
|
20
|
-
# warm up the JIT, etc
|
21
|
-
puts "Doing a warmup run..."
|
22
|
-
16000.times { x.publish(s, :routing_key => "anything") }
|
23
|
-
|
24
|
-
# give OS, the server and so on some time to catch
|
25
|
-
# up
|
26
|
-
sleep 2.0
|
27
|
-
|
28
|
-
result = RubyProf.profile do
|
29
|
-
n.times { x.publish(s, :routing_key => "anything") }
|
30
|
-
end
|
31
|
-
|
32
|
-
printer = RubyProf::FlatPrinter.new(result)
|
33
|
-
printer.print(STDOUT, {})
|
@@ -1,44 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Bunny::Queue, "backwards compatibility API" do
|
4
|
-
let(:connection) do
|
5
|
-
c = Bunny.new
|
6
|
-
c.start
|
7
|
-
c
|
8
|
-
end
|
9
|
-
|
10
|
-
after :all do
|
11
|
-
connection.close if connection.open?
|
12
|
-
end
|
13
|
-
|
14
|
-
context "when queue name is specified" do
|
15
|
-
let(:name) { "a queue declared at #{Time.now.to_i}" }
|
16
|
-
|
17
|
-
it "declares a new queue with that name" do
|
18
|
-
q = Bunny::Queue.new(connection, name)
|
19
|
-
q.name.should == name
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
|
24
|
-
context "when queue name is passed on as an empty string" do
|
25
|
-
it "uses server-assigned queue name" do
|
26
|
-
q = Bunny::Queue.new(connection, "")
|
27
|
-
q.name.should_not be_empty
|
28
|
-
q.name.should =~ /^amq.gen.+/
|
29
|
-
q.should be_server_named
|
30
|
-
q.delete
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
|
35
|
-
context "when queue name is completely omitted" do
|
36
|
-
it "uses server-assigned queue name" do
|
37
|
-
q = Bunny::Queue.new(connection)
|
38
|
-
q.name.should_not be_empty
|
39
|
-
q.name.should =~ /^amq.gen.+/
|
40
|
-
q.should be_server_named
|
41
|
-
q.delete
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Bunny::Session do
|
4
|
-
let(:connection) do
|
5
|
-
c = Bunny.new
|
6
|
-
c.start
|
7
|
-
c
|
8
|
-
end
|
9
|
-
|
10
|
-
after :all do
|
11
|
-
connection.close if connection.open?
|
12
|
-
end
|
13
|
-
|
14
|
-
it "proxies #queue to the pre-opened channel for backwards compatibility" do
|
15
|
-
q = connection.queue("", :exclusive => true)
|
16
|
-
q.name.should =~ /^amq.gen/
|
17
|
-
end
|
18
|
-
|
19
|
-
it "proxies #fanout to the pre-opened channel for backwards compatibility" do
|
20
|
-
x = connection.fanout("amq.fanout")
|
21
|
-
x.name.should == "amq.fanout"
|
22
|
-
end
|
23
|
-
|
24
|
-
it "proxies #topic to the pre-opened channel for backwards compatibility" do
|
25
|
-
x = connection.topic("amq.topic")
|
26
|
-
x.name.should == "amq.topic"
|
27
|
-
end
|
28
|
-
|
29
|
-
it "proxies #direct to the pre-opened channel for backwards compatibility" do
|
30
|
-
x = connection.topic("amq.direct")
|
31
|
-
x.name.should == "amq.direct"
|
32
|
-
end
|
33
|
-
end
|
@@ -1,71 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Bunny::Channel, "#ack" do
|
4
|
-
let(:connection) do
|
5
|
-
c = Bunny.new(:user => "bunny_gem", :password => "bunny_password", :vhost => "bunny_testbed")
|
6
|
-
c.start
|
7
|
-
c
|
8
|
-
end
|
9
|
-
|
10
|
-
after :each do
|
11
|
-
connection.close if connection.open?
|
12
|
-
end
|
13
|
-
|
14
|
-
context "with a valid (known) delivery tag" do
|
15
|
-
it "acknowledges a message" do
|
16
|
-
ch = connection.create_channel
|
17
|
-
q = ch.queue("bunny.basic.ack.manual-acks", :exclusive => true)
|
18
|
-
x = ch.default_exchange
|
19
|
-
|
20
|
-
x.publish("bunneth", :routing_key => q.name)
|
21
|
-
sleep 0.5
|
22
|
-
q.message_count.should == 1
|
23
|
-
delivery_details, properties, content = q.pop(:ack => true)
|
24
|
-
|
25
|
-
ch.ack(delivery_details.delivery_tag, true)
|
26
|
-
q.message_count.should == 0
|
27
|
-
|
28
|
-
ch.close
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
|
33
|
-
context "with a valid (known) delivery tag and automatic ack mode" do
|
34
|
-
it "results in a channel exception" do
|
35
|
-
ch = connection.create_channel
|
36
|
-
q = ch.queue("bunny.basic.ack.manual-acks", :exclusive => true)
|
37
|
-
x = ch.default_exchange
|
38
|
-
|
39
|
-
q.subscribe(:manual_ack => false) do |delivery_info, properties, payload|
|
40
|
-
ch.ack(delivery_info.delivery_tag, false)
|
41
|
-
end
|
42
|
-
|
43
|
-
x.publish("bunneth", :routing_key => q.name)
|
44
|
-
sleep 0.5
|
45
|
-
lambda do
|
46
|
-
q.message_count
|
47
|
-
end.should raise_error(Bunny::ChannelAlreadyClosed)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
context "with an invalid (random) delivery tag" do
|
52
|
-
it "causes a channel-level error" do
|
53
|
-
ch = connection.create_channel
|
54
|
-
q = ch.queue("bunny.basic.ack.unknown-delivery-tag", :exclusive => true)
|
55
|
-
x = ch.default_exchange
|
56
|
-
|
57
|
-
x.publish("bunneth", :routing_key => q.name)
|
58
|
-
sleep 0.5
|
59
|
-
q.message_count.should == 1
|
60
|
-
_, _, content = q.pop(:ack => true)
|
61
|
-
|
62
|
-
ch.on_error do |ch, channel_close|
|
63
|
-
@channel_close = channel_close
|
64
|
-
end
|
65
|
-
ch.ack(82, true)
|
66
|
-
sleep 0.25
|
67
|
-
|
68
|
-
@channel_close.reply_code.should == AMQ::Protocol::PreconditionFailed::VALUE
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|