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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8e682274ba299fe9da1e373641236dd929ad81784a68a8f873a0461343835980
4
- data.tar.gz: 9b5aba8b96ee2a5d7c1cf3f0df73ca93de5ce0e921da3df2e45fb165d6a28bbd
3
+ metadata.gz: 1021b405443096b923a6d84d00500e95303517d8dff0d71bb48ecd6c2c7d25a5
4
+ data.tar.gz: feb30475f0b4ab34599d2cee2cc68fc6d8aa129c69519770140a323696c8c3b6
5
5
  SHA512:
6
- metadata.gz: 7afd6d03c3c5c5691c5b34bab63a0deddb95d779bbaf1d80e011ade79856e65cc3677d77388a89cedfa9d56f70c528d88210e76aeff3b8d65b30026bee8cc5d6
7
- data.tar.gz: 28f0da296a9852c66a14cc19c1578168ccd549f0f1e9a0c9a143fb109d7ae57ab74c84a90569415219c039840ca59145420cc8e10f0a04413b10638d00ad3217
6
+ metadata.gz: 859cb4a6d243af0e3cfbb73db9b430d74430327ef9b12471eff91cc8d04588379a6f22ba29ae441c2fcff57e4431196319a82795d4ef752d4c6e9fdfae623dd6
7
+ data.tar.gz: 256a9aed9e7460d025dee8df1b5890cd2dc4461577c4221dc3c93bf7f656869b7877a92f7e931d6edbd3cda1c217b51022e3ebb132d03be4b289f06d75924141
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -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
- raise IOError unless (data.length > 0 || length == 0)
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
- raise IOError unless (chunk.length > 0 || length == 0)
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
- deadline = (Time.now + timeout) if timeout
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
- rescue IO::WaitReadable
236
- select_timeout = (deadline - Time.now) if deadline
237
- if (select_timeout && select_timeout <= 0) || !Kernel::select([@socket], nil, [@socket], select_timeout)
238
- raise Timeout::Error.new("Took more than #{timeout} seconds to receive data.")
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
@@ -33,9 +33,6 @@ module Mongo
33
33
  # @return [ Integer ] port The port to connect to.
34
34
  attr_reader :port
35
35
 
36
- # @return [ Float ] timeout The socket timeout.
37
- attr_reader :timeout
38
-
39
36
  # Establishes a socket connection.
40
37
  #
41
38
  # @example Connect the socket.
@@ -26,9 +26,6 @@ module Mongo
26
26
  # @return [ Integer ] port The port to connect to.
27
27
  attr_reader :port
28
28
 
29
- # @return [ Float ] timeout The socket timeout.
30
- attr_reader :timeout
31
-
32
29
  # Establishes a socket connection.
33
30
  #
34
31
  # @example Connect the socket.
@@ -23,9 +23,6 @@ module Mongo
23
23
  # @return [ String ] path The path to connect to.
24
24
  attr_reader :path
25
25
 
26
- # @return [ Float ] timeout The socket timeout.
27
- attr_reader :timeout
28
-
29
26
  # Initializes a new Unix socket.
30
27
  #
31
28
  # @example Create the Unix socket.
@@ -17,5 +17,5 @@ module Mongo
17
17
  # The current version of the driver.
18
18
  #
19
19
  # @since 2.0.0
20
- VERSION = '2.9.1.rc0'.freeze
20
+ VERSION = '2.9.1'.freeze
21
21
  end
@@ -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 'sets the timeout' do
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
- authorized_collection.delete_many
776
- authorized_collection.insert_one(a: 1)
780
+ client.cluster.next_primary
777
781
  end
778
782
 
779
- it 'raises a timeout when it expires' do
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(Timeout::Error)
788
- expect(ex.message).to eq("Took more than 1.5 seconds to receive data.")
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
- # Account for wait queue timeout (2s) and rescue
791
- expect(end_time - start).to be_within(2.5).of(1.5)
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(Timeout::Error)
823
+ }.to raise_exception(Mongo::Error::SocketTimeoutError)
820
824
  end
821
825
  end
822
826
  end
@@ -1,4 +1,4 @@
1
- require 'lite_spec_helper'
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?
@@ -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.rc0
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-06 00:00:00.000000000 Z
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: 1.3.1
1093
+ version: '0'
1094
1094
  requirements: []
1095
1095
  rubygems_version: 3.0.3
1096
1096
  signing_key:
metadata.gz.sig CHANGED
Binary file