mongo 2.7.2 → 2.8.0.rc0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +1 -3
- data/lib/mongo/address.rb +17 -20
- data/lib/mongo/address/ipv4.rb +6 -3
- data/lib/mongo/address/ipv6.rb +6 -3
- data/lib/mongo/address/unix.rb +5 -2
- data/lib/mongo/auth.rb +15 -2
- data/lib/mongo/auth/cr/conversation.rb +4 -2
- data/lib/mongo/auth/ldap/conversation.rb +4 -2
- data/lib/mongo/auth/scram.rb +3 -7
- data/lib/mongo/auth/scram/conversation.rb +28 -19
- data/lib/mongo/auth/user.rb +45 -10
- data/lib/mongo/auth/x509/conversation.rb +4 -2
- data/lib/mongo/cluster.rb +9 -17
- data/lib/mongo/error.rb +2 -0
- data/lib/mongo/error/missing_password.rb +29 -0
- data/lib/mongo/error/operation_failure.rb +7 -3
- data/lib/mongo/error/parser.rb +2 -1
- data/lib/mongo/error/sdam_error_detection.rb +54 -0
- data/lib/mongo/operation/aggregate/command.rb +1 -16
- data/lib/mongo/operation/aggregate/op_msg.rb +1 -1
- data/lib/mongo/operation/collections_info.rb +2 -3
- data/lib/mongo/operation/delete/command.rb +2 -15
- data/lib/mongo/operation/delete/legacy.rb +1 -16
- data/lib/mongo/operation/explain/command.rb +1 -16
- data/lib/mongo/operation/explain/legacy.rb +1 -16
- data/lib/mongo/operation/find/command.rb +1 -16
- data/lib/mongo/operation/find/legacy.rb +1 -16
- data/lib/mongo/operation/get_more/command.rb +1 -16
- data/lib/mongo/operation/indexes/command.rb +1 -16
- data/lib/mongo/operation/indexes/legacy.rb +4 -16
- data/lib/mongo/operation/list_collections/command.rb +1 -16
- data/lib/mongo/operation/map_reduce/command.rb +1 -16
- data/lib/mongo/operation/parallel_scan/command.rb +1 -16
- data/lib/mongo/operation/result.rb +3 -0
- data/lib/mongo/operation/shared/executable.rb +4 -0
- data/lib/mongo/operation/shared/polymorphic_lookup.rb +1 -1
- data/lib/mongo/operation/shared/polymorphic_result.rb +8 -1
- data/lib/mongo/operation/shared/result/aggregatable.rb +0 -5
- data/lib/mongo/operation/update/command.rb +2 -15
- data/lib/mongo/operation/update/legacy.rb +1 -16
- data/lib/mongo/operation/users_info/command.rb +1 -16
- data/lib/mongo/retryable.rb +22 -10
- data/lib/mongo/server.rb +10 -1
- data/lib/mongo/server/app_metadata.rb +7 -2
- data/lib/mongo/server/connectable.rb +0 -6
- data/lib/mongo/server/connection.rb +86 -135
- data/lib/mongo/server/connection_base.rb +133 -0
- data/lib/mongo/server/connection_pool.rb +11 -24
- data/lib/mongo/server/connection_pool/queue.rb +41 -41
- data/lib/mongo/server/description.rb +1 -1
- data/lib/mongo/server/monitor.rb +4 -4
- data/lib/mongo/server/monitor/connection.rb +26 -7
- data/lib/mongo/server/pending_connection.rb +36 -0
- data/lib/mongo/server_selector/selectable.rb +9 -1
- data/lib/mongo/session.rb +0 -1
- data/lib/mongo/socket.rb +23 -6
- data/lib/mongo/socket/ssl.rb +11 -18
- data/lib/mongo/socket/tcp.rb +13 -14
- data/lib/mongo/socket/unix.rb +9 -27
- data/lib/mongo/uri.rb +1 -1
- data/lib/mongo/version.rb +1 -1
- data/spec/integration/auth_spec.rb +160 -0
- data/spec/integration/retryable_writes_spec.rb +55 -58
- data/spec/integration/sdam_error_handling_spec.rb +115 -0
- data/spec/mongo/address/ipv4_spec.rb +4 -0
- data/spec/mongo/address/ipv6_spec.rb +4 -0
- data/spec/mongo/auth/scram/conversation_spec.rb +6 -5
- data/spec/mongo/auth/scram/negotiation_spec.rb +25 -36
- data/spec/mongo/auth/scram_spec.rb +2 -2
- data/spec/mongo/auth/user_spec.rb +97 -0
- data/spec/mongo/client_construction_spec.rb +1 -1
- data/spec/mongo/error/operation_failure_spec.rb +125 -1
- data/spec/mongo/retryable_spec.rb +17 -8
- data/spec/mongo/server/connection_pool/queue_spec.rb +24 -10
- data/spec/mongo/server/connection_pool_spec.rb +30 -117
- data/spec/mongo/server/connection_spec.rb +147 -25
- data/spec/mongo/server/description_spec.rb +0 -14
- data/spec/mongo/server/monitor/connection_spec.rb +22 -0
- data/spec/mongo/server_selector_spec.rb +1 -0
- data/spec/mongo/server_spec.rb +6 -6
- data/spec/mongo/socket/ssl_spec.rb +48 -116
- data/spec/mongo/socket/tcp_spec.rb +22 -0
- data/spec/mongo/socket/unix_spec.rb +9 -9
- data/spec/mongo/socket_spec.rb +15 -3
- data/spec/spec_tests/server_selection_spec.rb +2 -0
- data/spec/support/client_registry.rb +8 -2
- data/spec/support/common_shortcuts.rb +20 -1
- data/spec/support/constraints.rb +10 -2
- data/spec/support/lite_constraints.rb +8 -0
- data/spec/support/spec_config.rb +9 -1
- metadata +14 -4
- metadata.gz.sig +0 -0
@@ -26,22 +26,7 @@ module Mongo
|
|
26
26
|
include Executable
|
27
27
|
include Limited
|
28
28
|
include ReadPreferenceSupported
|
29
|
-
|
30
|
-
# Execute the operation.
|
31
|
-
#
|
32
|
-
# @example
|
33
|
-
# operation.execute(server)
|
34
|
-
#
|
35
|
-
# @param [ Mongo::Server ] server The server to send the operation to.
|
36
|
-
#
|
37
|
-
# @return [ Mongo::Operation::GetMore::Result ] The operation result.
|
38
|
-
#
|
39
|
-
# @since 2.5.2
|
40
|
-
def execute(server)
|
41
|
-
result = Result.new(dispatch_message(server))
|
42
|
-
process_result(result, server)
|
43
|
-
result.validate!
|
44
|
-
end
|
29
|
+
include PolymorphicResult
|
45
30
|
|
46
31
|
private
|
47
32
|
|
@@ -26,22 +26,7 @@ module Mongo
|
|
26
26
|
include Executable
|
27
27
|
include Limited
|
28
28
|
include ReadPreferenceSupported
|
29
|
-
|
30
|
-
# Execute the operation.
|
31
|
-
#
|
32
|
-
# @example
|
33
|
-
# operation.execute(server)
|
34
|
-
#
|
35
|
-
# @param [ Mongo::Server ] server The server to send the operation to.
|
36
|
-
#
|
37
|
-
# @return [ Mongo::Operation::Indexes::Result ] The operation result.
|
38
|
-
#
|
39
|
-
# @since 2.5.2
|
40
|
-
def execute(server)
|
41
|
-
result = Result.new(dispatch_message(server))
|
42
|
-
process_result(result, server)
|
43
|
-
result.validate!
|
44
|
-
end
|
29
|
+
include PolymorphicResult
|
45
30
|
|
46
31
|
private
|
47
32
|
|
@@ -26,22 +26,6 @@ module Mongo
|
|
26
26
|
include Executable
|
27
27
|
include ReadPreferenceSupported
|
28
28
|
|
29
|
-
# Execute the operation.
|
30
|
-
#
|
31
|
-
# @example
|
32
|
-
# operation.execute(server)
|
33
|
-
#
|
34
|
-
# @param [ Mongo::Server ] server The server to send the operation to.
|
35
|
-
#
|
36
|
-
# @return [ Mongo::Operation::Indexes::Result ] The operation result.
|
37
|
-
#
|
38
|
-
# @since 2.5.2
|
39
|
-
def execute(server)
|
40
|
-
result = Operation::Result.new(dispatch_message(server))
|
41
|
-
process_result(result, server)
|
42
|
-
result.validate!
|
43
|
-
end
|
44
|
-
|
45
29
|
private
|
46
30
|
|
47
31
|
def selector(server)
|
@@ -51,6 +35,10 @@ module Mongo
|
|
51
35
|
def message(server)
|
52
36
|
Protocol::Query.new(db_name, Index::COLLECTION, command(server), options(server))
|
53
37
|
end
|
38
|
+
|
39
|
+
def result_class
|
40
|
+
Operation::Result
|
41
|
+
end
|
54
42
|
end
|
55
43
|
end
|
56
44
|
end
|
@@ -26,22 +26,7 @@ module Mongo
|
|
26
26
|
include Executable
|
27
27
|
include Limited
|
28
28
|
include ReadPreferenceSupported
|
29
|
-
|
30
|
-
# Execute the operation.
|
31
|
-
#
|
32
|
-
# @example
|
33
|
-
# operation.execute(server)
|
34
|
-
#
|
35
|
-
# @param [ Mongo::Server ] server The server to send the operation to.
|
36
|
-
#
|
37
|
-
# @return [ Mongo::Operation::ListCollections::Result ] The operation result.
|
38
|
-
#
|
39
|
-
# @since 2.5.2
|
40
|
-
def execute(server)
|
41
|
-
result = Result.new(dispatch_message(server))
|
42
|
-
process_result(result, server)
|
43
|
-
result.validate!
|
44
|
-
end
|
29
|
+
include PolymorphicResult
|
45
30
|
|
46
31
|
private
|
47
32
|
|
@@ -27,22 +27,7 @@ module Mongo
|
|
27
27
|
include Limited
|
28
28
|
include ReadPreferenceSupported
|
29
29
|
include WriteConcernSupported
|
30
|
-
|
31
|
-
# Execute the operation.
|
32
|
-
#
|
33
|
-
# @example
|
34
|
-
# operation.execute(server)
|
35
|
-
#
|
36
|
-
# @param [ Mongo::Server ] server The server to send the operation to.
|
37
|
-
#
|
38
|
-
# @return [ Mongo::Operation::MapReduce::Result ] The operation result.
|
39
|
-
#
|
40
|
-
# @since 2.5.2
|
41
|
-
def execute(server)
|
42
|
-
result = Result.new(dispatch_message(server))
|
43
|
-
process_result(result, server)
|
44
|
-
result.validate!
|
45
|
-
end
|
30
|
+
include PolymorphicResult
|
46
31
|
|
47
32
|
private
|
48
33
|
|
@@ -26,22 +26,7 @@ module Mongo
|
|
26
26
|
include Executable
|
27
27
|
include Limited
|
28
28
|
include ReadPreferenceSupported
|
29
|
-
|
30
|
-
# Execute the operation.
|
31
|
-
#
|
32
|
-
# @example
|
33
|
-
# operation.execute(server)
|
34
|
-
#
|
35
|
-
# @param [ Mongo::Server ] server The server to send the operation to.
|
36
|
-
#
|
37
|
-
# @return [ Mongo::Operation::ParallelScan::Result ] The operation result.
|
38
|
-
#
|
39
|
-
# @since 2.5.2
|
40
|
-
def execute(server)
|
41
|
-
result = Result.new(dispatch_message(server))
|
42
|
-
process_result(result, server)
|
43
|
-
result.validate!
|
44
|
-
end
|
29
|
+
include PolymorphicResult
|
45
30
|
|
46
31
|
private
|
47
32
|
|
@@ -79,6 +79,9 @@ module Mongo
|
|
79
79
|
# @return [ Array<Protocol::Reply> ] replies The wrapped wire protocol replies.
|
80
80
|
attr_reader :replies
|
81
81
|
|
82
|
+
def_delegators :parser,
|
83
|
+
:not_master?, :node_recovering?
|
84
|
+
|
82
85
|
# Is the result acknowledged?
|
83
86
|
#
|
84
87
|
# @note On MongoDB 2.6 and higher all writes are acknowledged since the
|
@@ -45,6 +45,10 @@ module Mongo
|
|
45
45
|
|
46
46
|
def process_result(result, server)
|
47
47
|
server.update_cluster_time(result)
|
48
|
+
if result.not_master? || result.node_recovering?
|
49
|
+
server.unknown!
|
50
|
+
server.monitor.scan_semaphore.signal
|
51
|
+
end
|
48
52
|
session.process(result) if session
|
49
53
|
result
|
50
54
|
end
|
@@ -18,6 +18,9 @@ module Mongo
|
|
18
18
|
# Shared behavior of instantiating a result class matching the
|
19
19
|
# operation class.
|
20
20
|
#
|
21
|
+
# This module must be included after Executable module because result_class
|
22
|
+
# is defined in both.
|
23
|
+
#
|
21
24
|
# @api private
|
22
25
|
module PolymorphicResult
|
23
26
|
include PolymorphicLookup
|
@@ -25,7 +28,11 @@ module Mongo
|
|
25
28
|
private
|
26
29
|
|
27
30
|
def result_class
|
28
|
-
|
31
|
+
begin
|
32
|
+
polymorphic_class(self.class.name, :Result)
|
33
|
+
rescue NameError
|
34
|
+
polymorphic_class(self.class.name.sub(/::[^:]*$/, ''), :Result)
|
35
|
+
end
|
29
36
|
end
|
30
37
|
end
|
31
38
|
end
|
@@ -27,21 +27,8 @@ module Mongo
|
|
27
27
|
include Limited
|
28
28
|
include WriteConcernSupported
|
29
29
|
include BypassDocumentValidation
|
30
|
-
|
31
|
-
|
32
|
-
#
|
33
|
-
# @example
|
34
|
-
# operation.execute(server)
|
35
|
-
#
|
36
|
-
# @param [ Mongo::Server ] server The server to send the operation to.
|
37
|
-
#
|
38
|
-
# @return [ Mongo::Operation::Update::Result ] The operation result.
|
39
|
-
#
|
40
|
-
# @since 2.5.2
|
41
|
-
def execute(server)
|
42
|
-
result = Result.new(dispatch_message(server))
|
43
|
-
process_result(result, server)
|
44
|
-
end
|
30
|
+
include ExecutableNoValidate
|
31
|
+
include PolymorphicResult
|
45
32
|
|
46
33
|
private
|
47
34
|
|
@@ -26,22 +26,7 @@ module Mongo
|
|
26
26
|
class Legacy
|
27
27
|
include Specifiable
|
28
28
|
include Executable
|
29
|
-
|
30
|
-
# Execute the operation.
|
31
|
-
#
|
32
|
-
# @example
|
33
|
-
# operation.execute(server)
|
34
|
-
#
|
35
|
-
# @param [ Mongo::Server ] server The server to send the operation to.
|
36
|
-
#
|
37
|
-
# @return [ Mongo::Operation::Update::Result ] The operation result.
|
38
|
-
#
|
39
|
-
# @since 2.5.2
|
40
|
-
def execute(server)
|
41
|
-
result = Result.new(dispatch_message(server))
|
42
|
-
process_result(result, server)
|
43
|
-
result.validate!
|
44
|
-
end
|
29
|
+
include PolymorphicResult
|
45
30
|
|
46
31
|
private
|
47
32
|
|
@@ -26,22 +26,7 @@ module Mongo
|
|
26
26
|
include Executable
|
27
27
|
include Limited
|
28
28
|
include ReadPreferenceSupported
|
29
|
-
|
30
|
-
# Execute the operation.
|
31
|
-
#
|
32
|
-
# @example
|
33
|
-
# operation.execute(server)
|
34
|
-
#
|
35
|
-
# @param [ Mongo::Server ] server The server to send the operation to.
|
36
|
-
#
|
37
|
-
# @return [ Mongo::Operation::UsersInfo::Result ] The operation result.
|
38
|
-
#
|
39
|
-
# @since 2.5.2
|
40
|
-
def execute(server)
|
41
|
-
result = Result.new(dispatch_message(server))
|
42
|
-
process_result(result, server)
|
43
|
-
result.validate!
|
44
|
-
end
|
29
|
+
include PolymorphicResult
|
45
30
|
|
46
31
|
private
|
47
32
|
|
data/lib/mongo/retryable.rb
CHANGED
@@ -42,18 +42,22 @@ module Mongo
|
|
42
42
|
attempt += 1
|
43
43
|
yield
|
44
44
|
rescue Error::SocketError, Error::SocketTimeoutError => e
|
45
|
-
|
45
|
+
if attempt > cluster.max_read_retries || (session && session.in_transaction?)
|
46
|
+
raise
|
47
|
+
end
|
46
48
|
log_retry(e)
|
47
49
|
cluster.scan!(false)
|
48
50
|
retry
|
49
51
|
rescue Error::OperationFailure => e
|
50
52
|
if cluster.sharded? && e.retryable? && !(session && session.in_transaction?)
|
51
|
-
|
53
|
+
if attempt > cluster.max_read_retries
|
54
|
+
raise
|
55
|
+
end
|
52
56
|
log_retry(e)
|
53
57
|
sleep(cluster.read_retry_interval)
|
54
58
|
retry
|
55
59
|
else
|
56
|
-
raise
|
60
|
+
raise
|
57
61
|
end
|
58
62
|
end
|
59
63
|
end
|
@@ -141,10 +145,14 @@ module Mongo
|
|
141
145
|
txn_num = session.in_transaction? ? session.txn_num : session.next_txn_num
|
142
146
|
yield(server, txn_num, false)
|
143
147
|
rescue Error::SocketError, Error::SocketTimeoutError => e
|
144
|
-
|
148
|
+
if session.in_transaction? && !ending_transaction
|
149
|
+
raise
|
150
|
+
end
|
145
151
|
retry_write(e, txn_num, &block)
|
146
152
|
rescue Error::OperationFailure => e
|
147
|
-
|
153
|
+
if (session.in_transaction? && !ending_transaction) || !e.write_retryable?
|
154
|
+
raise
|
155
|
+
end
|
148
156
|
retry_write(e, txn_num, &block)
|
149
157
|
end
|
150
158
|
end
|
@@ -167,17 +175,19 @@ module Mongo
|
|
167
175
|
end
|
168
176
|
|
169
177
|
def retry_write(original_error, txn_num, &block)
|
170
|
-
cluster
|
178
|
+
# We do not request a scan of the cluster here, because error handling
|
179
|
+
# for the error which triggered the retry should have updated the
|
180
|
+
# server description and/or topology as necessary (specifically,
|
181
|
+
# a socket error or a not master error should have marked the respective
|
182
|
+
# server unknown). Here we just need to wait for server selection.
|
171
183
|
server = cluster.next_primary
|
172
184
|
raise original_error unless (server.retry_writes? && txn_num)
|
173
185
|
log_retry(original_error)
|
174
186
|
yield(server, txn_num, true)
|
175
187
|
rescue Error::SocketError, Error::SocketTimeoutError => e
|
176
|
-
cluster.scan!(false)
|
177
188
|
raise e
|
178
189
|
rescue Error::OperationFailure => e
|
179
190
|
raise original_error unless e.write_retryable?
|
180
|
-
cluster.scan!(false)
|
181
191
|
raise e
|
182
192
|
rescue
|
183
193
|
raise original_error
|
@@ -193,13 +203,15 @@ module Mongo
|
|
193
203
|
yield(server || cluster.next_primary)
|
194
204
|
rescue Error::OperationFailure => e
|
195
205
|
server = nil
|
196
|
-
|
206
|
+
if attempt > Cluster::MAX_WRITE_RETRIES
|
207
|
+
raise
|
208
|
+
end
|
197
209
|
if e.write_retryable? && !(session && session.in_transaction?)
|
198
210
|
log_retry(e)
|
199
211
|
cluster.scan!(false)
|
200
212
|
retry
|
201
213
|
else
|
202
|
-
raise
|
214
|
+
raise
|
203
215
|
end
|
204
216
|
end
|
205
217
|
end
|
data/lib/mongo/server.rb
CHANGED
@@ -67,6 +67,7 @@ module Mongo
|
|
67
67
|
start_monitoring
|
68
68
|
end
|
69
69
|
@connected = true
|
70
|
+
@pool_lock = Mutex.new
|
70
71
|
end
|
71
72
|
|
72
73
|
# @return [ String ] The configured address for the server.
|
@@ -280,7 +281,13 @@ module Mongo
|
|
280
281
|
#
|
281
282
|
# @since 2.0.0
|
282
283
|
def pool
|
283
|
-
@
|
284
|
+
@pool_lock.synchronize do
|
285
|
+
@pool ||= begin
|
286
|
+
ConnectionPool.new(options) do |generation|
|
287
|
+
Connection.new(self, options.merge(generation: generation))
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
284
291
|
end
|
285
292
|
|
286
293
|
# Determine if the provided tags are a subset of the server's tags.
|
@@ -401,6 +408,8 @@ end
|
|
401
408
|
|
402
409
|
require 'mongo/server/app_metadata'
|
403
410
|
require 'mongo/server/connectable'
|
411
|
+
require 'mongo/server/connection_base'
|
412
|
+
require 'mongo/server/pending_connection'
|
404
413
|
require 'mongo/server/connection'
|
405
414
|
require 'mongo/server/connection_pool'
|
406
415
|
require 'mongo/server/context'
|
@@ -32,14 +32,19 @@ module Mongo
|
|
32
32
|
|
33
33
|
# The max application name byte size.
|
34
34
|
#
|
35
|
-
# @
|
35
|
+
# @since 2.4.0
|
36
36
|
MAX_APP_NAME_SIZE = 128.freeze
|
37
37
|
|
38
38
|
# The driver name.
|
39
39
|
#
|
40
|
-
# @
|
40
|
+
# @since 2.4.0
|
41
41
|
DRIVER_NAME = 'mongo-ruby-driver'
|
42
42
|
|
43
|
+
# Option keys that affect auth mechanism negotiation.
|
44
|
+
#
|
45
|
+
# @api private
|
46
|
+
AUTH_OPTION_KEYS = [:user, :auth_source, :auth_mech].freeze
|
47
|
+
|
43
48
|
# Instantiate the new AppMetadata object.
|
44
49
|
#
|
45
50
|
# @api private
|
@@ -34,12 +34,6 @@ module Mongo
|
|
34
34
|
# Will be removed in driver version 3.0.
|
35
35
|
TIMEOUT = 5.freeze
|
36
36
|
|
37
|
-
# @return [ Mongo::Address ] address The address to connect to.
|
38
|
-
attr_reader :address
|
39
|
-
|
40
|
-
# @return [ Hash ] options The passed in options.
|
41
|
-
attr_reader :options
|
42
|
-
|
43
37
|
# @return [ Integer ] pid The process id when the connection was created.
|
44
38
|
attr_reader :pid
|
45
39
|
|