mongo 2.9.1.rc0 → 2.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/mongo/socket.rb +28 -7
- data/lib/mongo/socket/ssl.rb +0 -3
- data/lib/mongo/socket/tcp.rb +0 -3
- data/lib/mongo/socket/unix.rb +0 -3
- data/lib/mongo/version.rb +1 -1
- data/spec/mongo/server/connection_spec.rb +15 -11
- data/spec/mongo/socket_spec.rb +62 -1
- data/spec/support/cluster_config.rb +14 -0
- data/spec/support/spec_config.rb +0 -1
- metadata +4 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1021b405443096b923a6d84d00500e95303517d8dff0d71bb48ecd6c2c7d25a5
|
4
|
+
data.tar.gz: feb30475f0b4ab34599d2cee2cc68fc6d8aa129c69519770140a323696c8c3b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 859cb4a6d243af0e3cfbb73db9b430d74430327ef9b12471eff91cc8d04588379a6f22ba29ae441c2fcff57e4431196319a82795d4ef752d4c6e9fdfae623dd6
|
7
|
+
data.tar.gz: 256a9aed9e7460d025dee8df1b5890cd2dc4461577c4221dc3c93bf7f656869b7877a92f7e931d6edbd3cda1c217b51022e3ebb132d03be4b289f06d75924141
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/mongo/socket.rb
CHANGED
@@ -49,6 +49,9 @@ module Mongo
|
|
49
49
|
# @return [ Hash ] The options.
|
50
50
|
attr_reader :options
|
51
51
|
|
52
|
+
# @return [ Float ] timeout The socket timeout.
|
53
|
+
attr_reader :timeout
|
54
|
+
|
52
55
|
# Is the socket connection alive?
|
53
56
|
#
|
54
57
|
# @example Is the socket alive?
|
@@ -123,10 +126,14 @@ module Mongo
|
|
123
126
|
def read(length)
|
124
127
|
handle_errors do
|
125
128
|
data = read_from_socket(length)
|
126
|
-
|
129
|
+
unless (data.length > 0 || length == 0)
|
130
|
+
raise IOError, "Expected to read > 0 bytes but read 0 bytes"
|
131
|
+
end
|
127
132
|
while data.length < length
|
128
133
|
chunk = read_from_socket(length - data.length)
|
129
|
-
|
134
|
+
unless (chunk.length > 0 || length == 0)
|
135
|
+
raise IOError, "Expected to read > 0 bytes but read 0 bytes"
|
136
|
+
end
|
130
137
|
data << chunk
|
131
138
|
end
|
132
139
|
data
|
@@ -185,7 +192,9 @@ module Mongo
|
|
185
192
|
return ''.force_encoding('BINARY')
|
186
193
|
end
|
187
194
|
|
188
|
-
|
195
|
+
if _timeout = self.timeout
|
196
|
+
deadline = Time.now + _timeout
|
197
|
+
end
|
189
198
|
|
190
199
|
# We want to have a fixed and reasonably small size buffer for reads
|
191
200
|
# because, for example, OpenSSL reads in 16 kb chunks max.
|
@@ -232,10 +241,22 @@ module Mongo
|
|
232
241
|
data[retrieved, chunk.length] = chunk
|
233
242
|
retrieved += chunk.length
|
234
243
|
end
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
244
|
+
# As explained in https://ruby-doc.com/core-trunk/IO.html#method-c-select,
|
245
|
+
# reading from a TLS socket may require writing which may raise WaitWritable
|
246
|
+
rescue IO::WaitReadable, IO::WaitWritable => exc
|
247
|
+
if deadline
|
248
|
+
select_timeout = deadline - Time.now
|
249
|
+
if select_timeout <= 0
|
250
|
+
raise Errno::ETIMEDOUT, "Took more than #{_timeout} seconds to receive data"
|
251
|
+
end
|
252
|
+
end
|
253
|
+
if exc.is_a?(IO::WaitReadable)
|
254
|
+
select_args = [[@socket], nil, [@socket], select_timeout]
|
255
|
+
else
|
256
|
+
select_args = [nil, [@socket], [@socket], select_timeout]
|
257
|
+
end
|
258
|
+
unless Kernel::select(*select_args)
|
259
|
+
raise Errno::ETIMEDOUT, "Took more than #{_timeout} seconds to receive data"
|
239
260
|
end
|
240
261
|
retry
|
241
262
|
end
|
data/lib/mongo/socket/ssl.rb
CHANGED
data/lib/mongo/socket/tcp.rb
CHANGED
data/lib/mongo/socket/unix.rb
CHANGED
data/lib/mongo/version.rb
CHANGED
@@ -757,26 +757,30 @@ describe Mongo::Server::Connection, retry: 3 do
|
|
757
757
|
end
|
758
758
|
end
|
759
759
|
|
760
|
-
context 'when a socket timeout is set' do
|
760
|
+
context 'when a socket timeout is set on client' do
|
761
761
|
|
762
762
|
let(:connection) do
|
763
763
|
described_class.new(server, socket_timeout: 10)
|
764
764
|
end
|
765
765
|
|
766
|
-
it '
|
766
|
+
it 'is propagated to connection timeout' do
|
767
767
|
expect(connection.timeout).to eq(10)
|
768
768
|
end
|
769
|
+
end
|
769
770
|
|
771
|
+
context 'when an operation never completes' do
|
770
772
|
let(:client) do
|
771
|
-
authorized_client.with(socket_timeout: 1.5
|
773
|
+
authorized_client.with(socket_timeout: 1.5,
|
774
|
+
# Read retries would cause the reads to be attempted twice,
|
775
|
+
# thus making the find take twice as long to time out.
|
776
|
+
retry_reads: false, max_read_retries: 0)
|
772
777
|
end
|
773
778
|
|
774
779
|
before do
|
775
|
-
|
776
|
-
authorized_collection.insert_one(a: 1)
|
780
|
+
client.cluster.next_primary
|
777
781
|
end
|
778
782
|
|
779
|
-
it '
|
783
|
+
it 'times out and raises SocketTimeoutError' do
|
780
784
|
start = Time.now
|
781
785
|
begin
|
782
786
|
Timeout::timeout(1.5 + 2) do
|
@@ -784,11 +788,11 @@ describe Mongo::Server::Connection, retry: 3 do
|
|
784
788
|
end
|
785
789
|
rescue => ex
|
786
790
|
end_time = Time.now
|
787
|
-
expect(ex).to be_a(
|
788
|
-
expect(ex.message).to
|
791
|
+
expect(ex).to be_a(Mongo::Error::SocketTimeoutError)
|
792
|
+
expect(ex.message).to match(/Took more than 1.5 seconds to receive data/)
|
789
793
|
end
|
790
|
-
#
|
791
|
-
expect(end_time - start).to be_within(
|
794
|
+
# allow 1.5 seconds +- 0.5 seconds
|
795
|
+
expect(end_time - start).to be_within(1).of(2)
|
792
796
|
end
|
793
797
|
|
794
798
|
context 'when the socket_timeout is negative' do
|
@@ -816,7 +820,7 @@ describe Mongo::Server::Connection, retry: 3 do
|
|
816
820
|
it 'raises a timeout error' do
|
817
821
|
expect {
|
818
822
|
reply
|
819
|
-
}.to raise_exception(
|
823
|
+
}.to raise_exception(Mongo::Error::SocketTimeoutError)
|
820
824
|
end
|
821
825
|
end
|
822
826
|
end
|
data/spec/mongo/socket_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Mongo::Socket do
|
4
4
|
|
@@ -51,4 +51,65 @@ describe Mongo::Socket do
|
|
51
51
|
end.to raise_error(Mongo::Error::SocketError, 'OpenSSL::SSL::SSLError: Test error (for fake-address) (MongoDB may not be configured with SSL support)')
|
52
52
|
end
|
53
53
|
end
|
54
|
+
|
55
|
+
describe '#read' do
|
56
|
+
let(:target_host) do
|
57
|
+
host = ClusterConfig.instance.primary_address_host
|
58
|
+
# Take ipv4 address
|
59
|
+
Socket.getaddrinfo(host, 0).detect { |ai| ai.first == 'AF_INET' }[3]
|
60
|
+
end
|
61
|
+
|
62
|
+
let(:socket) do
|
63
|
+
Mongo::Socket::TCP.new(target_host, ClusterConfig.instance.primary_address_port, 1, Socket::PF_INET)
|
64
|
+
end
|
65
|
+
|
66
|
+
let(:raw_socket) { socket.instance_variable_get('@socket') }
|
67
|
+
|
68
|
+
let(:wait_readable_class) do
|
69
|
+
Class.new(Exception) do
|
70
|
+
include IO::WaitReadable
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'timeout' do
|
75
|
+
|
76
|
+
shared_examples_for 'times out' do
|
77
|
+
it 'times out' do
|
78
|
+
expect(socket).to receive(:timeout).at_least(:once).and_return(0.2)
|
79
|
+
# When we raise WaitWritable, the socket object is ready for
|
80
|
+
# writing which makes the read method invoke read_nonblock many times
|
81
|
+
expect(raw_socket).to receive(:read_nonblock).at_least(:once) do |len, buf|
|
82
|
+
sleep 0.01
|
83
|
+
raise exception_class
|
84
|
+
end
|
85
|
+
|
86
|
+
expect do
|
87
|
+
socket.read(10)
|
88
|
+
end.to raise_error(Mongo::Error::SocketTimeoutError, /Took more than .* seconds to receive data \(for /)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'with WaitReadable' do
|
93
|
+
|
94
|
+
let(:exception_class) do
|
95
|
+
Class.new(Exception) do
|
96
|
+
include IO::WaitReadable
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it_behaves_like 'times out'
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'with WaitWritable' do
|
104
|
+
|
105
|
+
let(:exception_class) do
|
106
|
+
Class.new(Exception) do
|
107
|
+
include IO::WaitWritable
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
it_behaves_like 'times out'
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
54
115
|
end
|
@@ -74,6 +74,20 @@ class ClusterConfig
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
+
def primary_address_str
|
78
|
+
primary_address
|
79
|
+
end
|
80
|
+
|
81
|
+
def primary_address_host
|
82
|
+
both = primary_address_str
|
83
|
+
both.split(':').first
|
84
|
+
end
|
85
|
+
|
86
|
+
def primary_address_port
|
87
|
+
both = primary_address_str
|
88
|
+
both.split(':')[1] || 27017
|
89
|
+
end
|
90
|
+
|
77
91
|
# Try running a command on the admin database to see if the mongod was
|
78
92
|
# started with auth.
|
79
93
|
def auth_enabled?
|
data/spec/support/spec_config.rb
CHANGED
@@ -328,7 +328,6 @@ EOT
|
|
328
328
|
{
|
329
329
|
max_pool_size: 1,
|
330
330
|
heartbeat_frequency: 20,
|
331
|
-
max_read_retries: 5,
|
332
331
|
# The test suite seems to perform a number of operations
|
333
332
|
# requiring server selection. Hence a timeout of 1 here,
|
334
333
|
# together with e.g. a misconfigured replica set,
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.9.1
|
4
|
+
version: 2.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tyler Brock
|
@@ -31,7 +31,7 @@ cert_chain:
|
|
31
31
|
bMYVwXXhV8czdzgkQB/ZPWHSbEWXnmkze1mzvqWBCPOVXYrcnL9cnEl/RoxtS1hr
|
32
32
|
Db6Ac6mCUSYfYHBWpWqxjc45n70i5Xi1
|
33
33
|
-----END CERTIFICATE-----
|
34
|
-
date: 2019-08-
|
34
|
+
date: 2019-08-13 00:00:00.000000000 Z
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: bson
|
@@ -1088,9 +1088,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
1088
1088
|
version: '0'
|
1089
1089
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
1090
1090
|
requirements:
|
1091
|
-
- - "
|
1091
|
+
- - ">="
|
1092
1092
|
- !ruby/object:Gem::Version
|
1093
|
-
version:
|
1093
|
+
version: '0'
|
1094
1094
|
requirements: []
|
1095
1095
|
rubygems_version: 3.0.3
|
1096
1096
|
signing_key:
|
metadata.gz.sig
CHANGED
Binary file
|