mongo 2.1.0 → 2.1.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
  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