mongo 2.1.0 → 2.1.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
  SHA1:
3
- metadata.gz: d2c9b3e878a211c1145f6cbe09912ac0fa3c6463
4
- data.tar.gz: d18c8e33629e8915fab3fb76edefb8cc631f65af
3
+ metadata.gz: d8c7fcad401a8586ae8ba1c0b864238fce8039a2
4
+ data.tar.gz: 9499b901d192abf1910f71a47fa0316633c32c31
5
5
  SHA512:
6
- metadata.gz: a6ded8b81178ac9561d5f9a3a8ec83edb31dec5528b8365e83f7d24b1b673e23276c1061956db19879d10feb602dacfeb34bbc7f51e5875fd4593ebfea0aa1c0
7
- data.tar.gz: 9431cb7dbb2b2b6a18292f454d84835ddbcee391f2a886bd93d398d3f9190a199f9d7a0f6fc2fc27eb95d32b59d900e6fc09317c2b66ec797fc12a42dabaf87c
6
+ metadata.gz: 5b4532f3365fda5b9351e334a882e92ccaa7fb0c006fa84b3e5e0bb922f9a8b3a5a7366f00ad1b505d0d7d4298c5438b5e57a5ce0f397105c8f49835618681b3
7
+ data.tar.gz: 262cb8675d073741690971aa9e141fb53324de2a3835f6e0e024b8faa654fba1aa3c451b4711793ef1e7df0d039e765675c5cb4bf1d1229a214ab70389dac379
Binary file
@@ -36,8 +36,8 @@ module Mongo
36
36
  # @return [ Hash ] options The configuration options.
37
37
  attr_reader :options
38
38
 
39
- # Delegate command execution to the current database.
40
- def_delegators :@database, :command
39
+ # Delegate command and collections execution to the current database.
40
+ def_delegators :@database, :command, :collections
41
41
 
42
42
  # Delegate subscription to monitoring.
43
43
  def_delegators :@monitoring, :subscribe, :unsubscribe
@@ -151,6 +151,10 @@ module Mongo
151
151
  # @option options [ Logger ] :logger A custom logger if desired.
152
152
  # @option options [ true, false ] :truncate_logs Whether to truncate the
153
153
  # logs at the default 250 characters.
154
+ # @option options [ Integer ] :max_read_retries The maximum number of read
155
+ # retries on mongos query failures.
156
+ # @option options [ Float ] :read_retry_interval The interval, in seconds,
157
+ # in which reads on a mongos are retried.
154
158
  #
155
159
  # @since 2.0.0
156
160
  def initialize(addresses_or_uri, options = Options::Redacted.new)
@@ -25,6 +25,16 @@ module Mongo
25
25
  include Event::Subscriber
26
26
  include Loggable
27
27
 
28
+ # The default number of mongos read retries.
29
+ #
30
+ # @since 2.1.1
31
+ MAX_READ_RETRIES = 1
32
+
33
+ # The default mongos read retry interval, in seconds.
34
+ #
35
+ # @since 2.1.1
36
+ READ_RETRY_INTERVAL = 5
37
+
28
38
  # @return [ Hash ] The options hash.
29
39
  attr_reader :options
30
40
 
@@ -143,6 +153,32 @@ module Mongo
143
153
  @topology = topology.elect_primary(description, servers_list)
144
154
  end
145
155
 
156
+ # Get the maximum number of times the cluster can retry a read operation on
157
+ # a mongos.
158
+ #
159
+ # @example Get the max read retries.
160
+ # cluster.max_read_retries
161
+ #
162
+ # @return [ Integer ] The maximum retries.
163
+ #
164
+ # @since 2.1.1
165
+ def max_read_retries
166
+ options[:max_read_retries] || MAX_READ_RETRIES
167
+ end
168
+
169
+ # Get the interval, in seconds, in which a mongos read operation is
170
+ # retried.
171
+ #
172
+ # @example Get the read retry interval.
173
+ # cluster.read_retry_interval
174
+ #
175
+ # @return [ Float ] The interval.
176
+ #
177
+ # @since 2.1.1
178
+ def read_retry_interval
179
+ options[:read_retry_interval] || READ_RETRY_INTERVAL
180
+ end
181
+
146
182
  # Notify the cluster that a standalone server was discovered so that the
147
183
  # topology can be updated accordingly.
148
184
  #
@@ -138,7 +138,7 @@ module Mongo
138
138
  cmd[:limit] = options[:limit] if options[:limit]
139
139
  cmd[:maxTimeMS] = options[:max_time_ms] if options[:max_time_ms]
140
140
  read_with_retry do
141
- database.command(cmd, options).n
141
+ database.command(cmd, options).n.to_i
142
142
  end
143
143
  end
144
144
 
@@ -18,6 +18,37 @@ module Mongo
18
18
  # Raised when an operation fails for some reason.
19
19
  #
20
20
  # @since 2.0.0
21
- class OperationFailure < Error; end
21
+ class OperationFailure < Error
22
+
23
+ # These are magic error messages that could indicate a cluster
24
+ # reconfiguration behind a mongos. We cannot check error codes as they
25
+ # change between versions, for example 15988 which has 2 completely
26
+ # different meanings between 2.4 and 3.0.
27
+ #
28
+ # @since 2.1.1
29
+ RETRY_MESSAGES = [
30
+ 'transport error',
31
+ 'socket exception',
32
+ "can't connect",
33
+ 'no master',
34
+ 'not master',
35
+ 'connect failed',
36
+ 'error querying',
37
+ 'could not get last error',
38
+ 'connection attempt failed'
39
+ ].freeze
40
+
41
+ # Can the operation that caused the error be retried?
42
+ #
43
+ # @example Is the error retryable?
44
+ # error.retryable?
45
+ #
46
+ # @return [ true, false ] If the error is retryable.
47
+ #
48
+ # @since 2.1.1
49
+ def retryable?
50
+ RETRY_MESSAGES.any?{ |m| message.include?(m) }
51
+ end
52
+ end
22
53
  end
23
54
  end
@@ -26,6 +26,8 @@ module Mongo
26
26
 
27
27
  # Execute a read operation with a retry.
28
28
  #
29
+ # @api private
30
+ #
29
31
  # @example Execute the read.
30
32
  # read_with_retry do
31
33
  # ...
@@ -33,21 +35,35 @@ module Mongo
33
35
  #
34
36
  # @note This only retries read operations on socket errors.
35
37
  #
38
+ # @param [ Integer ] attempt The retry attempt count - for internal use.
36
39
  # @param [ Proc ] block The block to execute.
37
40
  #
38
41
  # @return [ Result ] The result of the operation.
39
42
  #
40
43
  # @since 2.1.0
41
- def read_with_retry(&block)
44
+ def read_with_retry(attempt = 0, &block)
42
45
  begin
43
46
  block.call
44
47
  rescue Error::SocketError, Error::SocketTimeoutError
45
48
  retry_operation(&block)
49
+ rescue Error::OperationFailure => e
50
+ if cluster.sharded? && e.retryable?
51
+ if attempt < cluster.max_read_retries
52
+ # We don't scan the cluster in this case as Mongos always returns
53
+ # ready after a ping no matter what the state behind it is.
54
+ sleep(cluster.read_retry_interval)
55
+ read_with_retry(attempt - 1, &block)
56
+ end
57
+ else
58
+ raise e
59
+ end
46
60
  end
47
61
  end
48
62
 
49
63
  # Execute a write operation with a retry.
50
64
  #
65
+ # @api private
66
+ #
51
67
  # @example Execute the write.
52
68
  # write_with_retry do
53
69
  # ...
@@ -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.1.0'.freeze
20
+ VERSION = '2.1.1'.freeze
21
21
  end
@@ -742,4 +742,24 @@ describe Mongo::Client do
742
742
  expect(client.dup.options).to be_a(Mongo::Options::Redacted)
743
743
  end
744
744
  end
745
+
746
+ describe '#collections' do
747
+
748
+ before do
749
+ authorized_client.database[:users].create
750
+ end
751
+
752
+ after do
753
+ authorized_client.database[:users].drop
754
+ end
755
+
756
+ let(:collection) do
757
+ Mongo::Collection.new(authorized_client.database, 'users')
758
+ end
759
+
760
+ it 'refers the current database collections' do
761
+ expect(authorized_client.collections).to include(collection)
762
+ expect(authorized_client.collections).to all(be_a(Mongo::Collection))
763
+ end
764
+ end
745
765
  end
@@ -227,6 +227,10 @@ describe Mongo::Collection::View::Readable do
227
227
  it 'returns the count of matching documents' do
228
228
  expect(view.count).to eq(1)
229
229
  end
230
+
231
+ it 'returns an integer' do
232
+ expect(view.count).to be_a(Integer)
233
+ end
230
234
  end
231
235
 
232
236
  context 'when no selector is provided' do
@@ -14,6 +14,14 @@ describe Mongo::Retryable do
14
14
  @cluster = cluster
15
15
  end
16
16
 
17
+ def max_read_retries
18
+ cluster.max_read_retries
19
+ end
20
+
21
+ def read_retry_interval
22
+ cluster.read_retry_interval
23
+ end
24
+
17
25
  def read
18
26
  read_with_retry do
19
27
  operation.execute
@@ -81,14 +89,80 @@ describe Mongo::Retryable do
81
89
 
82
90
  context 'when an operation failure occurs' do
83
91
 
84
- before do
85
- expect(operation).to receive(:execute).and_raise(Mongo::Error::OperationFailure).ordered
92
+ context 'when the cluster is not a mongos' do
93
+
94
+ before do
95
+ expect(operation).to receive(:execute).and_raise(Mongo::Error::OperationFailure).ordered
96
+ expect(cluster).to receive(:sharded?).and_return(false)
97
+ end
98
+
99
+ it 'raises an exception' do
100
+ expect {
101
+ retryable.read
102
+ }.to raise_error(Mongo::Error::OperationFailure)
103
+ end
86
104
  end
87
105
 
88
- it 'raises an exception' do
89
- expect {
90
- retryable.read
91
- }.to raise_error(Mongo::Error::OperationFailure)
106
+ context 'when the cluster is a mongos' do
107
+
108
+ context 'when the operation failure is not retryable' do
109
+
110
+ let(:error) do
111
+ Mongo::Error::OperationFailure.new('not authorized')
112
+ end
113
+
114
+ before do
115
+ expect(operation).to receive(:execute).and_raise(error).ordered
116
+ expect(cluster).to receive(:sharded?).and_return(true)
117
+ end
118
+
119
+ it 'raises the exception' do
120
+ expect {
121
+ retryable.read
122
+ }.to raise_error(Mongo::Error::OperationFailure)
123
+ end
124
+ end
125
+
126
+ context 'when the operation failure is retryable' do
127
+
128
+ let(:error) do
129
+ Mongo::Error::OperationFailure.new('no master')
130
+ end
131
+
132
+ context 'when the retry succeeds' do
133
+
134
+ before do
135
+ expect(operation).to receive(:execute).and_raise(error).ordered
136
+ expect(cluster).to receive(:sharded?).and_return(true)
137
+ expect(cluster).to receive(:max_read_retries).and_return(1).ordered
138
+ expect(cluster).to receive(:read_retry_interval).and_return(0.1).ordered
139
+ expect(operation).to receive(:execute).and_return(true).ordered
140
+ end
141
+
142
+ it 'returns the result' do
143
+ expect(retryable.read).to be true
144
+ end
145
+ end
146
+
147
+ context 'when the retry fails once and then succeeds' do
148
+
149
+ before do
150
+ expect(operation).to receive(:execute).and_raise(error).ordered
151
+ expect(cluster).to receive(:sharded?).and_return(true)
152
+ expect(cluster).to receive(:max_read_retries).and_return(1).ordered
153
+ expect(cluster).to receive(:read_retry_interval).and_return(0.1).ordered
154
+ expect(operation).to receive(:execute).and_raise(error).ordered
155
+ expect(cluster).to receive(:sharded?).and_return(true)
156
+ expect(cluster).to receive(:max_read_retries).and_return(1).ordered
157
+ expect(cluster).to receive(:read_retry_interval).and_return(0.1).ordered
158
+ expect(operation).to receive(:execute).and_return(true).ordered
159
+ end
160
+
161
+ it 'returns the result' do
162
+ expect(retryable.read).to be true
163
+ end
164
+ end
165
+ end
92
166
  end
93
167
  end
94
168
  end
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.1.0
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Brock
@@ -9,30 +9,8 @@ authors:
9
9
  - Durran Jordan
10
10
  autorequire:
11
11
  bindir: bin
12
- cert_chain:
13
- - |
14
- -----BEGIN CERTIFICATE-----
15
- MIIDfDCCAmSgAwIBAgIBATANBgkqhkiG9w0BAQUFADBCMRQwEgYDVQQDDAtkcml2
16
- ZXItcnVieTEVMBMGCgmSJomT8ixkARkWBTEwZ2VuMRMwEQYKCZImiZPyLGQBGRYD
17
- Y29tMB4XDTE0MTEyMDE1NTYxOVoXDTE1MTEyMDE1NTYxOVowQjEUMBIGA1UEAwwL
18
- ZHJpdmVyLXJ1YnkxFTATBgoJkiaJk/IsZAEZFgUxMGdlbjETMBEGCgmSJomT8ixk
19
- ARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANFdSAa8fRm1
20
- bAM9za6Z0fAH4g02bqM1NGnw8zJQrE/PFrFfY6IFCT2AsLfOwr1maVm7iU1+kdVI
21
- IQ+iI/9+E+ArJ+rbGV3dDPQ+SLl3mLT+vXjfjcxMqI2IW6UuVtt2U3Rxd4QU0kdT
22
- JxmcPYs5fDN6BgYc6XXgUjy3m+Kwha2pGctdciUOwEfOZ4RmNRlEZKCMLRHdFP8j
23
- 4WTnJSGfXDiuoXICJb5yOPOZPuaapPSNXp93QkUdsqdKC32I+KMpKKYGBQ6yisfA
24
- 5MyVPPCzLR1lP5qXVGJPnOqUAkvEUfCahg7EP9tI20qxiXrR6TSEraYhIFXL0EGY
25
- u8KAcPHm5KkCAwEAAaN9MHswCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
26
- BBYEFFt3WbF+9JpUjAoj62cQBgNb8HzXMCAGA1UdEQQZMBeBFWRyaXZlci1ydWJ5
27
- QDEwZ2VuLmNvbTAgBgNVHRIEGTAXgRVkcml2ZXItcnVieUAxMGdlbi5jb20wDQYJ
28
- KoZIhvcNAQEFBQADggEBAKjvumG2Fy9zAoSc1OEcmAqqOfzx1U+isGyEsz1rs5eT
29
- HAIHsxaEdZTjSwDuqyelLDWJHWspeWU5pV5lepfI4cop29wwoPJIJ9Az2RMMbtdv
30
- gFApVb6QX61OMenFeOdJ/QZ3n9xcrxJZFdvrXQ5GjEU2anq3dJhFeESwIMlfVJC7
31
- 7XrlMxizzH712DPfy65dMj0Y39qHdoWYKeCkEoj5UWNcHRK9xgaHJR6prlXrIhgb
32
- o2UXDbWtz5PqoFd8EgNJAn3+BG1pwC9S9pVFG3WPucfAx/bE8iq/vvchHei5Y/Vo
33
- aAz5f/hY4zFeYWvGDBHYEXE1rTN2hhMSyJscPcFbmz0=
34
- -----END CERTIFICATE-----
35
- date: 2015-09-10 00:00:00.000000000 Z
12
+ cert_chain: []
13
+ date: 2015-09-30 00:00:00.000000000 Z
36
14
  dependencies:
37
15
  - !ruby/object:Gem::Dependency
38
16
  name: bson
@@ -59,6 +37,7 @@ files:
59
37
  - README.md
60
38
  - Rakefile
61
39
  - bin/mongo_console
40
+ - lib/csasl/csasl.bundle
62
41
  - lib/mongo.rb
63
42
  - lib/mongo/address.rb
64
43
  - lib/mongo/address/ipv4.rb
@@ -542,7 +521,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
542
521
  version: '0'
543
522
  requirements: []
544
523
  rubyforge_project: mongo
545
- rubygems_version: 2.4.8
524
+ rubygems_version: 2.4.5.1
546
525
  signing_key:
547
526
  specification_version: 4
548
527
  summary: Ruby driver for MongoDB
@@ -1,5 +0,0 @@
1
- �"W5c��a�A��S��
2
- � !~���G �7U`A��K�$�
3
- pno�c��)o��u�� �$��
4
- +
5
- +I#W���l5���̿�:F��D;��#QnG��*OP:b�[Hٲ+�4�}�V�o}�).�kͯDjݦ�U�|) _�P@<a2*��'���N��!��)��ڴ8�dH>
data.tar.gz.sig DELETED
Binary file
metadata.gz.sig DELETED
Binary file