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 +4 -4
- data/lib/csasl/csasl.bundle +0 -0
- data/lib/mongo/client.rb +6 -2
- data/lib/mongo/cluster.rb +36 -0
- data/lib/mongo/collection/view/readable.rb +1 -1
- data/lib/mongo/error/operation_failure.rb +32 -1
- data/lib/mongo/retryable.rb +17 -1
- data/lib/mongo/version.rb +1 -1
- data/spec/mongo/client_spec.rb +20 -0
- data/spec/mongo/collection/view/readable_spec.rb +4 -0
- data/spec/mongo/retryable_spec.rb +80 -6
- metadata +5 -26
- checksums.yaml.gz.sig +0 -5
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8c7fcad401a8586ae8ba1c0b864238fce8039a2
|
4
|
+
data.tar.gz: 9499b901d192abf1910f71a47fa0316633c32c31
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b4532f3365fda5b9351e334a882e92ccaa7fb0c006fa84b3e5e0bb922f9a8b3a5a7366f00ad1b505d0d7d4298c5438b5e57a5ce0f397105c8f49835618681b3
|
7
|
+
data.tar.gz: 262cb8675d073741690971aa9e141fb53324de2a3835f6e0e024b8faa654fba1aa3c451b4711793ef1e7df0d039e765675c5cb4bf1d1229a214ab70389dac379
|
Binary file
|
data/lib/mongo/client.rb
CHANGED
@@ -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)
|
data/lib/mongo/cluster.rb
CHANGED
@@ -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
|
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
|
data/lib/mongo/retryable.rb
CHANGED
@@ -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
|
# ...
|
data/lib/mongo/version.rb
CHANGED
data/spec/mongo/client_spec.rb
CHANGED
@@ -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
|
-
|
85
|
-
|
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
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
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.
|
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.
|
524
|
+
rubygems_version: 2.4.5.1
|
546
525
|
signing_key:
|
547
526
|
specification_version: 4
|
548
527
|
summary: Ruby driver for MongoDB
|
checksums.yaml.gz.sig
DELETED
data.tar.gz.sig
DELETED
Binary file
|
metadata.gz.sig
DELETED
Binary file
|