garaio_bunny 2.19.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.
- checksums.yaml +7 -0
- data/README.md +231 -0
- data/lib/amq/protocol/extensions.rb +16 -0
- data/lib/bunny/authentication/credentials_encoder.rb +55 -0
- data/lib/bunny/authentication/external_mechanism_encoder.rb +27 -0
- data/lib/bunny/authentication/plain_mechanism_encoder.rb +19 -0
- data/lib/bunny/channel.rb +2055 -0
- data/lib/bunny/channel_id_allocator.rb +82 -0
- data/lib/bunny/concurrent/atomic_fixnum.rb +75 -0
- data/lib/bunny/concurrent/condition.rb +66 -0
- data/lib/bunny/concurrent/continuation_queue.rb +62 -0
- data/lib/bunny/concurrent/linked_continuation_queue.rb +61 -0
- data/lib/bunny/concurrent/synchronized_sorted_set.rb +56 -0
- data/lib/bunny/consumer.rb +128 -0
- data/lib/bunny/consumer_tag_generator.rb +23 -0
- data/lib/bunny/consumer_work_pool.rb +122 -0
- data/lib/bunny/cruby/socket.rb +110 -0
- data/lib/bunny/cruby/ssl_socket.rb +118 -0
- data/lib/bunny/delivery_info.rb +93 -0
- data/lib/bunny/exceptions.rb +269 -0
- data/lib/bunny/exchange.rb +275 -0
- data/lib/bunny/framing.rb +56 -0
- data/lib/bunny/get_response.rb +83 -0
- data/lib/bunny/heartbeat_sender.rb +71 -0
- data/lib/bunny/jruby/socket.rb +57 -0
- data/lib/bunny/jruby/ssl_socket.rb +58 -0
- data/lib/bunny/message_properties.rb +119 -0
- data/lib/bunny/queue.rb +393 -0
- data/lib/bunny/reader_loop.rb +158 -0
- data/lib/bunny/return_info.rb +74 -0
- data/lib/bunny/session.rb +1483 -0
- data/lib/bunny/socket.rb +14 -0
- data/lib/bunny/ssl_socket.rb +14 -0
- data/lib/bunny/test_kit.rb +41 -0
- data/lib/bunny/timeout.rb +7 -0
- data/lib/bunny/transport.rb +526 -0
- data/lib/bunny/version.rb +6 -0
- data/lib/bunny/versioned_delivery_tag.rb +28 -0
- data/lib/bunny.rb +92 -0
- metadata +127 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
require "socket"
|
|
2
|
+
|
|
3
|
+
module Bunny
|
|
4
|
+
# TCP socket extension that uses TCP_NODELAY and supports reading
|
|
5
|
+
# fully.
|
|
6
|
+
#
|
|
7
|
+
# Heavily inspired by Dalli by Mike Perham.
|
|
8
|
+
# @private
|
|
9
|
+
module Socket
|
|
10
|
+
attr_accessor :options
|
|
11
|
+
|
|
12
|
+
READ_RETRY_EXCEPTION_CLASSES = if defined?(IO::EAGAINWaitReadable)
|
|
13
|
+
# Ruby 2.1+
|
|
14
|
+
[Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitReadable,
|
|
15
|
+
IO::EAGAINWaitReadable, IO::EWOULDBLOCKWaitReadable]
|
|
16
|
+
else
|
|
17
|
+
# 2.0
|
|
18
|
+
[Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitReadable]
|
|
19
|
+
end
|
|
20
|
+
WRITE_RETRY_EXCEPTION_CLASSES = if defined?(IO::EAGAINWaitWritable)
|
|
21
|
+
[Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitWritable,
|
|
22
|
+
IO::EAGAINWaitWritable, IO::EWOULDBLOCKWaitWritable]
|
|
23
|
+
else
|
|
24
|
+
# 2.0
|
|
25
|
+
[Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitWritable]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.open(host, port, options = {})
|
|
29
|
+
socket = ::Socket.tcp(host, port, nil, nil,
|
|
30
|
+
connect_timeout: options[:connect_timeout])
|
|
31
|
+
if ::Socket.constants.include?('TCP_NODELAY') || ::Socket.constants.include?(:TCP_NODELAY)
|
|
32
|
+
socket.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, true)
|
|
33
|
+
end
|
|
34
|
+
socket.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_KEEPALIVE, true) if options.fetch(:keepalive, true)
|
|
35
|
+
socket.instance_eval do
|
|
36
|
+
@__bunny_socket_eof_flag__ = false
|
|
37
|
+
end
|
|
38
|
+
socket.extend self
|
|
39
|
+
socket.options = { :host => host, :port => port }.merge(options)
|
|
40
|
+
socket
|
|
41
|
+
rescue Errno::ETIMEDOUT
|
|
42
|
+
raise ClientTimeout
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Reads given number of bytes with an optional timeout
|
|
46
|
+
#
|
|
47
|
+
# @param [Integer] count How many bytes to read
|
|
48
|
+
# @param [Integer] timeout Timeout
|
|
49
|
+
#
|
|
50
|
+
# @return [String] Data read from the socket
|
|
51
|
+
# @api public
|
|
52
|
+
def read_fully(count, timeout = nil)
|
|
53
|
+
return nil if @__bunny_socket_eof_flag__
|
|
54
|
+
|
|
55
|
+
value = ''
|
|
56
|
+
begin
|
|
57
|
+
loop do
|
|
58
|
+
value << read_nonblock(count - value.bytesize)
|
|
59
|
+
break if value.bytesize >= count
|
|
60
|
+
end
|
|
61
|
+
rescue EOFError
|
|
62
|
+
# @eof will break Rubinius' TCPSocket implementation. MK.
|
|
63
|
+
@__bunny_socket_eof_flag__ = true
|
|
64
|
+
rescue *READ_RETRY_EXCEPTION_CLASSES
|
|
65
|
+
if IO.select([self], nil, nil, timeout)
|
|
66
|
+
retry
|
|
67
|
+
else
|
|
68
|
+
raise Timeout::Error, "IO timeout when reading #{count} bytes"
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
value
|
|
72
|
+
end # read_fully
|
|
73
|
+
|
|
74
|
+
# Writes provided data using IO#write_nonblock, taking care of handling
|
|
75
|
+
# of exceptions it raises when writing would fail (e.g. due to socket buffer
|
|
76
|
+
# being full).
|
|
77
|
+
#
|
|
78
|
+
# IMPORTANT: this method will mutate (slice) the argument. Pass in duplicates
|
|
79
|
+
# if this is not appropriate in your case.
|
|
80
|
+
#
|
|
81
|
+
# @param [String] data Data to write
|
|
82
|
+
# @param [Integer] timeout Timeout
|
|
83
|
+
#
|
|
84
|
+
# @api public
|
|
85
|
+
def write_nonblock_fully(data, timeout = nil)
|
|
86
|
+
return nil if @__bunny_socket_eof_flag__
|
|
87
|
+
|
|
88
|
+
length = data.bytesize
|
|
89
|
+
total_count = 0
|
|
90
|
+
count = 0
|
|
91
|
+
loop do
|
|
92
|
+
begin
|
|
93
|
+
count = self.write_nonblock(data)
|
|
94
|
+
rescue *WRITE_RETRY_EXCEPTION_CLASSES
|
|
95
|
+
if IO.select([], [self], nil, timeout)
|
|
96
|
+
retry
|
|
97
|
+
else
|
|
98
|
+
raise Timeout::Error, "IO timeout when writing to socket"
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
total_count += count
|
|
103
|
+
return total_count if total_count >= length
|
|
104
|
+
data = data.byteslice(count..-1)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
require "socket"
|
|
2
|
+
|
|
3
|
+
module Bunny
|
|
4
|
+
begin
|
|
5
|
+
require "openssl"
|
|
6
|
+
|
|
7
|
+
# TLS-enabled TCP socket that implements convenience
|
|
8
|
+
# methods found in Bunny::Socket.
|
|
9
|
+
class SSLSocket < OpenSSL::SSL::SSLSocket
|
|
10
|
+
|
|
11
|
+
READ_RETRY_EXCEPTION_CLASSES = if defined?(IO::EAGAINWaitReadable)
|
|
12
|
+
# Ruby 2.1+
|
|
13
|
+
[Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitReadable,
|
|
14
|
+
IO::EAGAINWaitReadable, IO::EWOULDBLOCKWaitReadable]
|
|
15
|
+
else
|
|
16
|
+
# 2.0
|
|
17
|
+
[Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitReadable]
|
|
18
|
+
end
|
|
19
|
+
WRITE_RETRY_EXCEPTION_CLASSES = if defined?(IO::EAGAINWaitWritable)
|
|
20
|
+
[Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitWritable,
|
|
21
|
+
IO::EAGAINWaitWritable, IO::EWOULDBLOCKWaitWritable]
|
|
22
|
+
else
|
|
23
|
+
# 2.0
|
|
24
|
+
[Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitWritable]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def initialize(*args)
|
|
28
|
+
super
|
|
29
|
+
@__bunny_socket_eof_flag__ = false
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Reads given number of bytes with an optional timeout
|
|
33
|
+
#
|
|
34
|
+
# @param [Integer] count How many bytes to read
|
|
35
|
+
# @param [Integer] timeout Timeout
|
|
36
|
+
#
|
|
37
|
+
# @return [String] Data read from the socket
|
|
38
|
+
# @api public
|
|
39
|
+
def read_fully(count, timeout = nil)
|
|
40
|
+
return nil if @__bunny_socket_eof_flag__
|
|
41
|
+
|
|
42
|
+
value = ''
|
|
43
|
+
begin
|
|
44
|
+
loop do
|
|
45
|
+
value << read_nonblock(count - value.bytesize)
|
|
46
|
+
break if value.bytesize >= count
|
|
47
|
+
end
|
|
48
|
+
rescue EOFError => e
|
|
49
|
+
@__bunny_socket_eof_flag__ = true
|
|
50
|
+
rescue OpenSSL::SSL::SSLError => e
|
|
51
|
+
if e.message == "read would block"
|
|
52
|
+
if IO.select([self], nil, nil, timeout)
|
|
53
|
+
retry
|
|
54
|
+
else
|
|
55
|
+
raise Timeout::Error, "IO timeout when reading #{count} bytes"
|
|
56
|
+
end
|
|
57
|
+
else
|
|
58
|
+
raise e
|
|
59
|
+
end
|
|
60
|
+
rescue *READ_RETRY_EXCEPTION_CLASSES => e
|
|
61
|
+
if IO.select([self], nil, nil, timeout)
|
|
62
|
+
retry
|
|
63
|
+
else
|
|
64
|
+
raise Timeout::Error, "IO timeout when reading #{count} bytes"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
value
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Writes provided data using IO#write_nonblock, taking care of handling
|
|
71
|
+
# of exceptions it raises when writing would fail (e.g. due to socket buffer
|
|
72
|
+
# being full).
|
|
73
|
+
#
|
|
74
|
+
# IMPORTANT: this method will mutate (slice) the argument. Pass in duplicates
|
|
75
|
+
# if this is not appropriate in your case.
|
|
76
|
+
#
|
|
77
|
+
# @param [String] data Data to write
|
|
78
|
+
# @param [Integer] timeout Timeout
|
|
79
|
+
#
|
|
80
|
+
# @api public
|
|
81
|
+
def write_nonblock_fully(data, timeout = nil)
|
|
82
|
+
return nil if @__bunny_socket_eof_flag__
|
|
83
|
+
|
|
84
|
+
length = data.bytesize
|
|
85
|
+
total_count = 0
|
|
86
|
+
count = 0
|
|
87
|
+
loop do
|
|
88
|
+
begin
|
|
89
|
+
count = self.write_nonblock(data)
|
|
90
|
+
rescue OpenSSL::SSL::SSLError => e
|
|
91
|
+
if e.message == "write would block"
|
|
92
|
+
if IO.select([], [self], nil, timeout)
|
|
93
|
+
retry
|
|
94
|
+
else
|
|
95
|
+
raise Timeout::Error, "IO timeout when writing to socket"
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
raise e
|
|
99
|
+
rescue *WRITE_RETRY_EXCEPTION_CLASSES
|
|
100
|
+
if IO.select([], [self], nil, timeout)
|
|
101
|
+
retry
|
|
102
|
+
else
|
|
103
|
+
raise Timeout::Error, "IO timeout when writing to socket"
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
total_count += count
|
|
108
|
+
return total_count if total_count >= length
|
|
109
|
+
data = data.byteslice(count..-1)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
end
|
|
115
|
+
rescue LoadError
|
|
116
|
+
puts "Could not load OpenSSL"
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
require "bunny/versioned_delivery_tag"
|
|
2
|
+
|
|
3
|
+
module Bunny
|
|
4
|
+
# Wraps {AMQ::Protocol::Basic::Deliver} to
|
|
5
|
+
# provide access to the delivery properties as immutable hash as
|
|
6
|
+
# well as methods.
|
|
7
|
+
class DeliveryInfo
|
|
8
|
+
|
|
9
|
+
#
|
|
10
|
+
# Behaviors
|
|
11
|
+
#
|
|
12
|
+
|
|
13
|
+
include Enumerable
|
|
14
|
+
|
|
15
|
+
#
|
|
16
|
+
# API
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
# @return [Bunny::Consumer] Consumer this delivery is for
|
|
20
|
+
attr_reader :consumer
|
|
21
|
+
# @return [Bunny::Channel] Channel this delivery is on
|
|
22
|
+
attr_reader :channel
|
|
23
|
+
|
|
24
|
+
# @private
|
|
25
|
+
def initialize(basic_deliver, consumer, channel)
|
|
26
|
+
@basic_deliver = basic_deliver
|
|
27
|
+
@hash = {
|
|
28
|
+
:consumer_tag => basic_deliver.consumer_tag,
|
|
29
|
+
:delivery_tag => VersionedDeliveryTag.new(basic_deliver.delivery_tag, channel.recoveries_counter),
|
|
30
|
+
:redelivered => basic_deliver.redelivered,
|
|
31
|
+
:exchange => basic_deliver.exchange,
|
|
32
|
+
:routing_key => basic_deliver.routing_key,
|
|
33
|
+
:consumer => consumer,
|
|
34
|
+
:channel => channel
|
|
35
|
+
}
|
|
36
|
+
@consumer = consumer
|
|
37
|
+
@channel = channel
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Iterates over the delivery properties
|
|
41
|
+
# @see Enumerable#each
|
|
42
|
+
def each(*args, &block)
|
|
43
|
+
@hash.each(*args, &block)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Accesses delivery properties by key
|
|
47
|
+
# @see Hash#[]
|
|
48
|
+
def [](k)
|
|
49
|
+
@hash[k]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @return [Hash] Hash representation of this delivery info
|
|
53
|
+
def to_hash
|
|
54
|
+
@hash
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# @private
|
|
58
|
+
def to_s
|
|
59
|
+
to_hash.to_s
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# @private
|
|
63
|
+
def inspect
|
|
64
|
+
to_hash.inspect
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# @return [String] Consumer tag this delivery is for
|
|
68
|
+
def consumer_tag
|
|
69
|
+
@basic_deliver.consumer_tag
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# @return [String] Delivery identifier that is used to acknowledge, reject and nack deliveries
|
|
73
|
+
def delivery_tag
|
|
74
|
+
@basic_deliver.delivery_tag
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# @return [Boolean] true if this delivery is a redelivery (the message was requeued at least once)
|
|
78
|
+
def redelivered
|
|
79
|
+
@basic_deliver.redelivered
|
|
80
|
+
end
|
|
81
|
+
alias redelivered? redelivered
|
|
82
|
+
|
|
83
|
+
# @return [String] Name of the exchange this message was published to
|
|
84
|
+
def exchange
|
|
85
|
+
@basic_deliver.exchange
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# @return [String] Routing key this message was published with
|
|
89
|
+
def routing_key
|
|
90
|
+
@basic_deliver.routing_key
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
module Bunny
|
|
2
|
+
# Base class for all Bunny exceptions
|
|
3
|
+
# @api public
|
|
4
|
+
class Exception < ::StandardError
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
class HostListDepleted < Exception
|
|
8
|
+
def initialize
|
|
9
|
+
super("No more hosts to try in the supplied list of hosts")
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Indicates a network failure. If automatic network
|
|
14
|
+
# recovery mode is enabled, these will be typically handled
|
|
15
|
+
# by the client itself.
|
|
16
|
+
#
|
|
17
|
+
# @api public
|
|
18
|
+
class NetworkFailure < Exception
|
|
19
|
+
attr_reader :cause
|
|
20
|
+
|
|
21
|
+
def initialize(message, cause)
|
|
22
|
+
super(message)
|
|
23
|
+
@cause = cause
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Base class for all channel level exceptions
|
|
28
|
+
class ChannelLevelException < Exception
|
|
29
|
+
attr_reader :channel, :channel_close
|
|
30
|
+
|
|
31
|
+
def initialize(message, ch, channel_close)
|
|
32
|
+
super(message)
|
|
33
|
+
|
|
34
|
+
@channel = ch
|
|
35
|
+
@channel_close = channel_close
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Base class for all connection level exceptions
|
|
40
|
+
class ConnectionLevelException < Exception
|
|
41
|
+
attr_reader :connection, :connection_close
|
|
42
|
+
|
|
43
|
+
def initialize(message, connection, connection_close)
|
|
44
|
+
super(message)
|
|
45
|
+
|
|
46
|
+
@connection = connection
|
|
47
|
+
@connection_close = connection_close
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Can indicate either a channel or connection-level issue
|
|
52
|
+
class NotAllowedError < Exception
|
|
53
|
+
attr_reader :connection, :connection_close
|
|
54
|
+
|
|
55
|
+
def initialize(message, connection, connection_close = nil)
|
|
56
|
+
super(message)
|
|
57
|
+
|
|
58
|
+
@connection = connection
|
|
59
|
+
@connection_close = connection_close
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Raised when TCP connection to RabbitMQ fails because of an unresolved
|
|
64
|
+
# hostname, connectivity problem, etc
|
|
65
|
+
class TCPConnectionFailed < Exception
|
|
66
|
+
attr_reader :hostname, :port
|
|
67
|
+
|
|
68
|
+
def initialize(e, hostname=nil, port=nil)
|
|
69
|
+
m = case e
|
|
70
|
+
when String then
|
|
71
|
+
e
|
|
72
|
+
when ::Exception then
|
|
73
|
+
e.message
|
|
74
|
+
end
|
|
75
|
+
if hostname && port
|
|
76
|
+
super("Could not establish TCP connection to #{hostname}:#{port}: #{m}")
|
|
77
|
+
else
|
|
78
|
+
super(m)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
class TCPConnectionFailedForAllHosts < TCPConnectionFailed
|
|
84
|
+
def initialize
|
|
85
|
+
super("Could not establish TCP connection to any of the configured hosts", nil, nil)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Raised when a frame is sent over an already closed connection
|
|
90
|
+
class ConnectionClosedError < Exception
|
|
91
|
+
def initialize(frame)
|
|
92
|
+
if frame.respond_to?(:method_class)
|
|
93
|
+
super("Trying to send frame through a closed connection. Frame is #{frame.inspect}, method class is #{frame.method_class}")
|
|
94
|
+
else
|
|
95
|
+
super("Trying to send frame through a closed connection. Frame is #{frame.inspect}")
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
class ConnectionAlreadyClosed < Exception
|
|
101
|
+
def initialize
|
|
102
|
+
super('Connection has been already closed')
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
class ShutdownSignal < Exception
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Raised when RabbitMQ closes TCP connection before finishing connection
|
|
110
|
+
# sequence properly. This typically indicates an authentication issue.
|
|
111
|
+
class PossibleAuthenticationFailureError < Exception
|
|
112
|
+
|
|
113
|
+
#
|
|
114
|
+
# API
|
|
115
|
+
#
|
|
116
|
+
|
|
117
|
+
attr_reader :username, :vhost
|
|
118
|
+
|
|
119
|
+
def initialize(username, vhost, password_length)
|
|
120
|
+
@username = username
|
|
121
|
+
@vhost = vhost
|
|
122
|
+
|
|
123
|
+
super("Authentication with RabbitMQ failed. Please check your connection settings. Username: #{username}, vhost: #{vhost}, password length: #{password_length}")
|
|
124
|
+
end # initialize(settings)
|
|
125
|
+
end # PossibleAuthenticationFailureError
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
# Raised when RabbitMQ closes TCP connection due to an authentication failure.
|
|
129
|
+
# Relies on RabbitMQ 3.2 Authentication Failure Notifications extension:
|
|
130
|
+
# http://www.rabbitmq.com/auth-notification.html
|
|
131
|
+
class AuthenticationFailureError < PossibleAuthenticationFailureError
|
|
132
|
+
|
|
133
|
+
#
|
|
134
|
+
# API
|
|
135
|
+
#
|
|
136
|
+
|
|
137
|
+
attr_reader :username, :vhost
|
|
138
|
+
|
|
139
|
+
def initialize(username, vhost, password_length)
|
|
140
|
+
@username = username
|
|
141
|
+
@vhost = vhost
|
|
142
|
+
|
|
143
|
+
super(username, vhost, password_length)
|
|
144
|
+
end # initialize(settings)
|
|
145
|
+
end # AuthenticationFailureError
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
# backwards compatibility
|
|
149
|
+
# @private
|
|
150
|
+
ConnectionError = TCPConnectionFailed
|
|
151
|
+
# @private
|
|
152
|
+
ServerDownError = TCPConnectionFailed
|
|
153
|
+
|
|
154
|
+
# Raised when a channel is closed forcefully using rabbitmqctl
|
|
155
|
+
# or the management UI plugin
|
|
156
|
+
class ForcedChannelCloseError < ChannelLevelException; end
|
|
157
|
+
# Raised when a connection is closed forcefully using rabbitmqctl
|
|
158
|
+
# or the management UI plugin
|
|
159
|
+
class ForcedConnectionCloseError < ConnectionLevelException; end
|
|
160
|
+
# @private
|
|
161
|
+
class MessageError < ConnectionLevelException; end
|
|
162
|
+
# @private
|
|
163
|
+
class ProtocolError < ConnectionLevelException; end
|
|
164
|
+
# Raised when RabbitMQ reports and internal error
|
|
165
|
+
class InternalError < ConnectionLevelException; end
|
|
166
|
+
|
|
167
|
+
# Raised when read or write I/O operations time out (but only if
|
|
168
|
+
# a connection is configured to use them)
|
|
169
|
+
class ClientTimeout < Timeout::Error; end
|
|
170
|
+
# Raised on initial TCP connection timeout
|
|
171
|
+
class ConnectionTimeout < Timeout::Error; end
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
# Base exception class for data consistency and framing errors.
|
|
175
|
+
class InconsistentDataError < Exception
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Raised by adapters when frame does not end with {final octet AMQ::Protocol::Frame::FINAL_OCTET}.
|
|
179
|
+
# This suggest that there is a bug in adapter or AMQ broker implementation.
|
|
180
|
+
#
|
|
181
|
+
# @see https://www.rabbitmq.com/resources/specs/amqp0-9-1.pdf AMQP 0.9.1 specification (Section 2.3)
|
|
182
|
+
class NoFinalOctetError < InconsistentDataError
|
|
183
|
+
def initialize
|
|
184
|
+
super("Frame doesn't end with #{AMQ::Protocol::Frame::FINAL_OCTET} as it must, which means the size is miscalculated.")
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Raised by adapters when actual frame payload size in bytes is not equal
|
|
189
|
+
# to the size specified in that frame's header.
|
|
190
|
+
# This suggest that there is a bug in adapter or AMQ broker implementation.
|
|
191
|
+
#
|
|
192
|
+
# @see https://www.rabbitmq.com/resources/specs/amqp0-9-1.pdf AMQP 0.9.1 specification (Section 2.3)
|
|
193
|
+
class BadLengthError < InconsistentDataError
|
|
194
|
+
def initialize(expected_length, actual_length)
|
|
195
|
+
super("Frame payload should be #{expected_length} long, but it's #{actual_length} long.")
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Raised when a closed channel is used
|
|
200
|
+
class ChannelAlreadyClosed < Exception
|
|
201
|
+
attr_reader :channel
|
|
202
|
+
|
|
203
|
+
def initialize(message, ch)
|
|
204
|
+
super(message)
|
|
205
|
+
|
|
206
|
+
@channel = ch
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Raised when RabbitMQ responds with 406 PRECONDITION_FAILED
|
|
211
|
+
class PreconditionFailed < ChannelLevelException
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# Raised when RabbitMQ responds with 404 NOT_FOUND
|
|
215
|
+
class NotFound < ChannelLevelException
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Raised when RabbitMQ responds with 405 RESOUCE_LOCKED
|
|
219
|
+
class ResourceLocked < ChannelLevelException
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Raised when RabbitMQ responds with 403 ACCESS_REFUSED
|
|
223
|
+
class AccessRefused < ChannelLevelException
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Raised when RabbitMQ responds with 504 CHANNEL_ERROR
|
|
227
|
+
class ChannelError < ConnectionLevelException
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# Raised when RabbitMQ responds with 503 COMMAND_INVALID
|
|
231
|
+
class CommandInvalid < ConnectionLevelException
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# Raised when RabbitMQ responds with 501 FRAME_ERROR
|
|
235
|
+
class FrameError < ConnectionLevelException
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# Raised when RabbitMQ responds with 505 UNEXPECTED_FRAME
|
|
239
|
+
class UnexpectedFrame < ConnectionLevelException
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# Raised when RabbitMQ responds with 506 RESOURCE_ERROR
|
|
243
|
+
class ResourceError < ConnectionLevelException
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# @private
|
|
247
|
+
class NetworkErrorWrapper < Exception
|
|
248
|
+
attr_reader :other
|
|
249
|
+
|
|
250
|
+
def initialize(other)
|
|
251
|
+
super(other.message)
|
|
252
|
+
@other = other
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Raised when RabbitMQ responds with 302 CONNECTION_FORCED
|
|
257
|
+
# (which means the connection was closed using rabbitmqctl or
|
|
258
|
+
# RabbitMQ management UI)
|
|
259
|
+
class ConnectionForced < ConnectionLevelException
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# @private
|
|
263
|
+
class MissingTLSCertificateFile < Exception
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# @private
|
|
267
|
+
class MissingTLSKeyFile < Exception
|
|
268
|
+
end
|
|
269
|
+
end
|