bunny 2.23.0 → 3.0.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 +4 -4
- data/README.md +38 -36
- 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 +778 -150
- data/lib/bunny/channel_id_allocator.rb +2 -0
- data/lib/bunny/concurrent/atomic_fixnum.rb +2 -0
- data/lib/bunny/concurrent/condition.rb +2 -0
- data/lib/bunny/concurrent/continuation_queue.rb +2 -0
- data/lib/bunny/concurrent/exception_accumulator.rb +115 -0
- data/lib/bunny/concurrent/synchronized_sorted_set.rb +2 -0
- data/lib/bunny/consumer.rb +4 -11
- data/lib/bunny/consumer_tag_generator.rb +2 -0
- data/lib/bunny/consumer_work_pool.rb +2 -0
- data/lib/bunny/cruby/socket.rb +36 -2
- data/lib/bunny/cruby/ssl_socket.rb +44 -1
- data/lib/bunny/delivery_info.rb +23 -15
- data/lib/bunny/exceptions.rb +33 -2
- data/lib/bunny/exchange.rb +27 -13
- data/lib/bunny/framing.rb +2 -0
- data/lib/bunny/get_response.rb +20 -14
- data/lib/bunny/heartbeat_sender.rb +4 -2
- data/lib/bunny/message_properties.rb +2 -0
- data/lib/bunny/queue.rb +31 -39
- data/lib/bunny/reader_loop.rb +9 -7
- data/lib/bunny/return_info.rb +18 -11
- data/lib/bunny/session.rb +387 -63
- data/lib/bunny/socket.rb +7 -12
- data/lib/bunny/ssl_socket.rb +7 -12
- data/lib/bunny/test_kit.rb +1 -0
- data/lib/bunny/timeout.rb +2 -0
- data/lib/bunny/timestamp.rb +3 -1
- data/lib/bunny/topology_recovery_filter.rb +71 -0
- data/lib/bunny/topology_registry.rb +824 -0
- data/lib/bunny/transport.rb +54 -49
- data/lib/bunny/version.rb +2 -1
- data/lib/bunny.rb +2 -1
- metadata +25 -14
- data/lib/bunny/concurrent/linked_continuation_queue.rb +0 -61
- data/lib/bunny/jruby/socket.rb +0 -57
- data/lib/bunny/jruby/ssl_socket.rb +0 -58
- data/lib/bunny/versioned_delivery_tag.rb +0 -28
data/lib/bunny/transport.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "socket"
|
|
2
4
|
require "thread"
|
|
3
5
|
require "monitor"
|
|
@@ -70,7 +72,7 @@ module Bunny
|
|
|
70
72
|
@read_timeout = opts[:read_timeout] || DEFAULT_READ_TIMEOUT
|
|
71
73
|
@read_timeout = nil if @read_timeout == 0
|
|
72
74
|
|
|
73
|
-
@write_timeout = opts[:socket_timeout] # Backwards
|
|
75
|
+
@write_timeout = opts[:socket_timeout] # Backwards compatibility
|
|
74
76
|
|
|
75
77
|
@write_timeout ||= opts[:write_timeout] || DEFAULT_WRITE_TIMEOUT
|
|
76
78
|
@write_timeout = nil if @write_timeout == 0
|
|
@@ -151,51 +153,26 @@ module Bunny
|
|
|
151
153
|
block.call(@tls_context) if @tls_context
|
|
152
154
|
end
|
|
153
155
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
# Writes data to the socket. If read/write timeout was specified the operation will return after that
|
|
157
|
+
# amount of time has elapsed waiting for the socket.
|
|
158
|
+
def write(data)
|
|
159
|
+
return write_without_timeout(data) unless @write_timeout
|
|
158
160
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
end
|
|
164
|
-
end
|
|
165
|
-
rescue SystemCallError, Timeout::Error, Bunny::ConnectionError, IOError => e
|
|
166
|
-
@logger.error "Got an exception when sending data: #{e.message} (#{e.class.name})"
|
|
167
|
-
close
|
|
168
|
-
@status = :not_connected
|
|
169
|
-
|
|
170
|
-
if @session.automatically_recover?
|
|
171
|
-
@session.handle_network_failure(e)
|
|
172
|
-
else
|
|
173
|
-
@session_error_handler.raise(Bunny::NetworkFailure.new("detected a network failure: #{e.message}", e))
|
|
161
|
+
begin
|
|
162
|
+
if open?
|
|
163
|
+
@writes_mutex.synchronize do
|
|
164
|
+
@socket.write_nonblock_fully(data, @write_timeout)
|
|
174
165
|
end
|
|
175
166
|
end
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
def write(data)
|
|
181
|
-
return write_without_timeout(data) unless @write_timeout
|
|
167
|
+
rescue SystemCallError, Timeout::Error, Bunny::ConnectionError, IOError => e
|
|
168
|
+
@logger.error "Got an exception when sending data: #{e.message} (#{e.class.name})"
|
|
169
|
+
close
|
|
170
|
+
@status = :not_connected
|
|
182
171
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
end
|
|
188
|
-
end
|
|
189
|
-
rescue SystemCallError, Timeout::Error, Bunny::ConnectionError, IOError => e
|
|
190
|
-
@logger.error "Got an exception when sending data: #{e.message} (#{e.class.name})"
|
|
191
|
-
close
|
|
192
|
-
@status = :not_connected
|
|
193
|
-
|
|
194
|
-
if @session.automatically_recover?
|
|
195
|
-
@session.handle_network_failure(e)
|
|
196
|
-
else
|
|
197
|
-
@session_error_handler.raise(Bunny::NetworkFailure.new("detected a network failure: #{e.message}", e))
|
|
198
|
-
end
|
|
172
|
+
if @session.automatically_recover?
|
|
173
|
+
@session.handle_network_failure(e)
|
|
174
|
+
else
|
|
175
|
+
@session_error_handler.raise(Bunny::NetworkFailure.new("detected a network failure: #{e.message}", e))
|
|
199
176
|
end
|
|
200
177
|
end
|
|
201
178
|
end
|
|
@@ -203,8 +180,10 @@ module Bunny
|
|
|
203
180
|
# Writes data to the socket without timeout checks
|
|
204
181
|
def write_without_timeout(data, raise_exceptions = false)
|
|
205
182
|
begin
|
|
206
|
-
@writes_mutex.synchronize
|
|
207
|
-
|
|
183
|
+
@writes_mutex.synchronize do
|
|
184
|
+
@socket.write(data)
|
|
185
|
+
@socket.flush
|
|
186
|
+
end
|
|
208
187
|
rescue SystemCallError, Bunny::ConnectionError, IOError => e
|
|
209
188
|
close
|
|
210
189
|
raise e if raise_exceptions
|
|
@@ -223,7 +202,7 @@ module Bunny
|
|
|
223
202
|
# @private
|
|
224
203
|
def send_frame(frame)
|
|
225
204
|
if closed?
|
|
226
|
-
@session.handle_network_failure(ConnectionClosedError.new(frame))
|
|
205
|
+
@session.handle_network_failure(ConnectionClosedError.new(frame)) if @session.automatically_recover?
|
|
227
206
|
else
|
|
228
207
|
write(frame.encode)
|
|
229
208
|
end
|
|
@@ -235,7 +214,7 @@ module Bunny
|
|
|
235
214
|
# @private
|
|
236
215
|
def send_frame_without_timeout(frame)
|
|
237
216
|
if closed?
|
|
238
|
-
@session.handle_network_failure(ConnectionClosedError.new(frame))
|
|
217
|
+
@session.handle_network_failure(ConnectionClosedError.new(frame)) if @session.automatically_recover?
|
|
239
218
|
else
|
|
240
219
|
write_without_timeout(frame.encode)
|
|
241
220
|
end
|
|
@@ -282,7 +261,10 @@ module Bunny
|
|
|
282
261
|
# Exposed primarily for Bunny::Channel
|
|
283
262
|
# @private
|
|
284
263
|
def read_next_frame(opts = {})
|
|
285
|
-
|
|
264
|
+
@frame_header_buffer ||= String.new(capacity: 7)
|
|
265
|
+
@frame_header_buffer.clear
|
|
266
|
+
header = read_fully_into(@frame_header_buffer, 7)
|
|
267
|
+
|
|
286
268
|
type, channel, size = AMQ::Protocol::Frame.decode_header(header)
|
|
287
269
|
payload = if size > 0
|
|
288
270
|
read_fully(size)
|
|
@@ -301,8 +283,26 @@ module Bunny
|
|
|
301
283
|
AMQ::Protocol::Frame.new(type, payload, channel)
|
|
302
284
|
end
|
|
303
285
|
|
|
286
|
+
# @private
|
|
287
|
+
def read_fully_into(buffer, count)
|
|
288
|
+
begin
|
|
289
|
+
@socket.read_fully_into(buffer, count, @read_timeout)
|
|
290
|
+
rescue SystemCallError, Timeout::Error, Bunny::ConnectionError, IOError => e
|
|
291
|
+
@logger.error "Got an exception when receiving data: #{e.message} (#{e.class.name})"
|
|
292
|
+
close
|
|
293
|
+
@status = :not_connected
|
|
304
294
|
|
|
305
|
-
|
|
295
|
+
if @session.automatically_recover?
|
|
296
|
+
raise
|
|
297
|
+
else
|
|
298
|
+
@session_error_handler.raise(Bunny::NetworkFailure.new("detected a network failure: #{e.message}", e))
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
buffer
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
def self.reachable?(host, port, timeout)
|
|
306
306
|
begin
|
|
307
307
|
s = Bunny::SocketImpl.open(host, port,
|
|
308
308
|
:connect_timeout => timeout)
|
|
@@ -315,11 +315,16 @@ module Bunny
|
|
|
315
315
|
end
|
|
316
316
|
end
|
|
317
317
|
|
|
318
|
+
class << self
|
|
319
|
+
alias_method :reacheable?, :reachable?
|
|
320
|
+
end
|
|
321
|
+
|
|
318
322
|
def self.ping!(host, port, timeout)
|
|
319
|
-
raise ConnectionTimeout.new("#{host}:#{port} is unreachable") if !
|
|
323
|
+
raise ConnectionTimeout.new("#{host}:#{port} is unreachable") if !reachable?(host, port, timeout)
|
|
320
324
|
end
|
|
321
325
|
|
|
322
326
|
def initialize_socket
|
|
327
|
+
@logger.debug("Using connection timeout of #{@connect_timeout} when connecting to #{@host}:#{@port}")
|
|
323
328
|
begin
|
|
324
329
|
@socket = Bunny::SocketImpl.open(@host, @port,
|
|
325
330
|
:keepalive => @opts[:keepalive],
|
data/lib/bunny/version.rb
CHANGED
data/lib/bunny.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# -*- encoding: utf-8; mode: ruby -*-
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
require "timeout"
|
|
4
5
|
|
|
@@ -88,7 +89,7 @@ module Bunny
|
|
|
88
89
|
# @option connection_string_or_opts [Proc] :recovery_attempt_started (nil) Will be called before every connection recovery attempt
|
|
89
90
|
# @option connection_string_or_opts [Proc] :recovery_completed (nil) Will be called after successful connection recovery
|
|
90
91
|
# @option connection_string_or_opts [Boolean] :recover_from_connection_close (true) Should this connection recover after receiving a server-sent connection.close (e.g. connection was force closed)?
|
|
91
|
-
# @option connection_string_or_opts [Object] :session_error_handler (
|
|
92
|
+
# @option connection_string_or_opts [Object] :session_error_handler (ExceptionAccumulator.new) Object which responds to #raise that will act as a session error handler. Defaults to a Bunny::ExceptionAccumulator instance which stores exceptions for safe retrieval later. Can be set to Thread.current for legacy behavior (raises asynchronous exceptions in the creating thread).
|
|
92
93
|
#
|
|
93
94
|
# @option optz [String] :auth_mechanism ("PLAIN") Authentication mechanism, PLAIN or EXTERNAL
|
|
94
95
|
# @option optz [String] :locale ("PLAIN") Locale RabbitMQ should use
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bunny
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chris Duncan
|
|
@@ -9,10 +9,9 @@ authors:
|
|
|
9
9
|
- Jakub Stastny aka botanicus
|
|
10
10
|
- Michael S. Klishin
|
|
11
11
|
- Stefan Kaes
|
|
12
|
-
autorequire:
|
|
13
12
|
bindir: bin
|
|
14
13
|
cert_chain: []
|
|
15
|
-
date:
|
|
14
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
16
15
|
dependencies:
|
|
17
16
|
- !ruby/object:Gem::Dependency
|
|
18
17
|
name: amq-protocol
|
|
@@ -20,20 +19,34 @@ dependencies:
|
|
|
20
19
|
requirements:
|
|
21
20
|
- - "~>"
|
|
22
21
|
- !ruby/object:Gem::Version
|
|
23
|
-
version: '2.
|
|
22
|
+
version: '2.7'
|
|
23
|
+
type: :runtime
|
|
24
|
+
prerelease: false
|
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
26
|
+
requirements:
|
|
27
|
+
- - "~>"
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '2.7'
|
|
30
|
+
- !ruby/object:Gem::Dependency
|
|
31
|
+
name: logger
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
33
|
+
requirements:
|
|
34
|
+
- - "~>"
|
|
35
|
+
- !ruby/object:Gem::Version
|
|
36
|
+
version: '1'
|
|
24
37
|
- - ">="
|
|
25
38
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
39
|
+
version: '1.7'
|
|
27
40
|
type: :runtime
|
|
28
41
|
prerelease: false
|
|
29
42
|
version_requirements: !ruby/object:Gem::Requirement
|
|
30
43
|
requirements:
|
|
31
44
|
- - "~>"
|
|
32
45
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
46
|
+
version: '1'
|
|
34
47
|
- - ">="
|
|
35
48
|
- !ruby/object:Gem::Version
|
|
36
|
-
version:
|
|
49
|
+
version: '1.7'
|
|
37
50
|
- !ruby/object:Gem::Dependency
|
|
38
51
|
name: sorted_set
|
|
39
52
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -74,7 +87,7 @@ files:
|
|
|
74
87
|
- lib/bunny/concurrent/atomic_fixnum.rb
|
|
75
88
|
- lib/bunny/concurrent/condition.rb
|
|
76
89
|
- lib/bunny/concurrent/continuation_queue.rb
|
|
77
|
-
- lib/bunny/concurrent/
|
|
90
|
+
- lib/bunny/concurrent/exception_accumulator.rb
|
|
78
91
|
- lib/bunny/concurrent/synchronized_sorted_set.rb
|
|
79
92
|
- lib/bunny/consumer.rb
|
|
80
93
|
- lib/bunny/consumer_tag_generator.rb
|
|
@@ -87,8 +100,6 @@ files:
|
|
|
87
100
|
- lib/bunny/framing.rb
|
|
88
101
|
- lib/bunny/get_response.rb
|
|
89
102
|
- lib/bunny/heartbeat_sender.rb
|
|
90
|
-
- lib/bunny/jruby/socket.rb
|
|
91
|
-
- lib/bunny/jruby/ssl_socket.rb
|
|
92
103
|
- lib/bunny/message_properties.rb
|
|
93
104
|
- lib/bunny/queue.rb
|
|
94
105
|
- lib/bunny/reader_loop.rb
|
|
@@ -99,15 +110,16 @@ files:
|
|
|
99
110
|
- lib/bunny/test_kit.rb
|
|
100
111
|
- lib/bunny/timeout.rb
|
|
101
112
|
- lib/bunny/timestamp.rb
|
|
113
|
+
- lib/bunny/topology_recovery_filter.rb
|
|
114
|
+
- lib/bunny/topology_registry.rb
|
|
102
115
|
- lib/bunny/transport.rb
|
|
103
116
|
- lib/bunny/version.rb
|
|
104
|
-
- lib/bunny/versioned_delivery_tag.rb
|
|
105
117
|
homepage: http://rubybunny.info
|
|
106
118
|
licenses:
|
|
107
119
|
- MIT
|
|
108
120
|
metadata:
|
|
109
121
|
changelog_uri: https://github.com/ruby-amqp/bunny/blob/main/ChangeLog.md
|
|
110
|
-
|
|
122
|
+
source_code_uri: https://github.com/ruby-amqp/bunny/
|
|
111
123
|
rdoc_options: []
|
|
112
124
|
require_paths:
|
|
113
125
|
- lib
|
|
@@ -122,8 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
122
134
|
- !ruby/object:Gem::Version
|
|
123
135
|
version: '0'
|
|
124
136
|
requirements: []
|
|
125
|
-
rubygems_version:
|
|
126
|
-
signing_key:
|
|
137
|
+
rubygems_version: 4.0.6
|
|
127
138
|
specification_version: 4
|
|
128
139
|
summary: Popular easy to use Ruby client for RabbitMQ
|
|
129
140
|
test_files: []
|
|
@@ -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,57 +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
|
-
module Socket
|
|
9
|
-
include Bunny::Socket
|
|
10
|
-
|
|
11
|
-
def self.open(host, port, options = {})
|
|
12
|
-
socket = ::Socket.tcp(host, port, nil, nil,
|
|
13
|
-
connect_timeout: options[:connect_timeout])
|
|
14
|
-
if ::Socket.constants.include?('TCP_NODELAY') || ::Socket.constants.include?(:TCP_NODELAY)
|
|
15
|
-
socket.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, true)
|
|
16
|
-
end
|
|
17
|
-
socket.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_KEEPALIVE, true) if options.fetch(:keepalive, true)
|
|
18
|
-
socket.extend self
|
|
19
|
-
socket.options = { :host => host, :port => port }.merge(options)
|
|
20
|
-
socket
|
|
21
|
-
rescue Errno::ETIMEDOUT
|
|
22
|
-
raise ClientTimeout
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Reads given number of bytes with an optional timeout
|
|
26
|
-
#
|
|
27
|
-
# @param [Integer] count How many bytes to read
|
|
28
|
-
# @param [Integer] timeout Timeout
|
|
29
|
-
#
|
|
30
|
-
# @return [String] Data read from the socket
|
|
31
|
-
# @api public
|
|
32
|
-
def read_fully(count, timeout = nil)
|
|
33
|
-
value = ''
|
|
34
|
-
|
|
35
|
-
begin
|
|
36
|
-
loop do
|
|
37
|
-
value << read_nonblock(count - value.bytesize)
|
|
38
|
-
break if value.bytesize >= count
|
|
39
|
-
end
|
|
40
|
-
rescue EOFError
|
|
41
|
-
# JRuby specific fix via https://github.com/jruby/jruby/issues/1694#issuecomment-54873532
|
|
42
|
-
IO.select([self], nil, nil, timeout)
|
|
43
|
-
retry
|
|
44
|
-
rescue *READ_RETRY_EXCEPTION_CLASSES
|
|
45
|
-
if IO.select([self], nil, nil, timeout)
|
|
46
|
-
retry
|
|
47
|
-
else
|
|
48
|
-
raise Timeout::Error, "IO timeout when reading #{count} bytes"
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
value
|
|
53
|
-
end # read_fully
|
|
54
|
-
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
@@ -1,58 +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
|
-
def initialize(*args)
|
|
12
|
-
super
|
|
13
|
-
@__bunny_socket_eof_flag__ = false
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# Reads given number of bytes with an optional timeout
|
|
17
|
-
#
|
|
18
|
-
# @param [Integer] count How many bytes to read
|
|
19
|
-
# @param [Integer] timeout Timeout
|
|
20
|
-
#
|
|
21
|
-
# @return [String] Data read from the socket
|
|
22
|
-
# @api public
|
|
23
|
-
def read_fully(count, timeout = nil)
|
|
24
|
-
return nil if @__bunny_socket_eof_flag__
|
|
25
|
-
|
|
26
|
-
value = ''
|
|
27
|
-
begin
|
|
28
|
-
loop do
|
|
29
|
-
value << read_nonblock(count - value.bytesize)
|
|
30
|
-
break if value.bytesize >= count
|
|
31
|
-
end
|
|
32
|
-
rescue EOFError => e
|
|
33
|
-
@__bunny_socket_eof_flag__ = true
|
|
34
|
-
rescue OpenSSL::SSL::SSLError => e
|
|
35
|
-
if e.message == "read would block"
|
|
36
|
-
if IO.select([self], nil, nil, timeout)
|
|
37
|
-
retry
|
|
38
|
-
else
|
|
39
|
-
raise Timeout::Error, "IO timeout when reading #{count} bytes"
|
|
40
|
-
end
|
|
41
|
-
else
|
|
42
|
-
raise e
|
|
43
|
-
end
|
|
44
|
-
rescue *READ_RETRY_EXCEPTION_CLASSES => e
|
|
45
|
-
if IO.select([self], nil, nil, timeout)
|
|
46
|
-
retry
|
|
47
|
-
else
|
|
48
|
-
raise Timeout::Error, "IO timeout when reading #{count} bytes"
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
value
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
rescue LoadError => le
|
|
55
|
-
puts "Could not load OpenSSL"
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
module Bunny
|
|
2
|
-
# Wraps a delivery tag (which is an integer) so that {Bunny::Channel} could
|
|
3
|
-
# detect stale tags after connection recovery.
|
|
4
|
-
#
|
|
5
|
-
# @private
|
|
6
|
-
class VersionedDeliveryTag
|
|
7
|
-
attr_reader :tag
|
|
8
|
-
attr_reader :version
|
|
9
|
-
|
|
10
|
-
def initialize(tag, version)
|
|
11
|
-
raise ArgumentError.new("tag cannot be nil") unless tag
|
|
12
|
-
raise ArgumentError.new("version cannot be nil") unless version
|
|
13
|
-
|
|
14
|
-
@tag = tag.to_i
|
|
15
|
-
@version = version.to_i
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def to_i
|
|
19
|
-
@tag
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def stale?(version)
|
|
23
|
-
raise ArgumentError.new("version cannot be nil") unless version
|
|
24
|
-
|
|
25
|
-
@version < version.to_i
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|