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