mongo 2.9.1.rc0 → 2.9.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 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