mongo 2.10.5 → 2.11.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 +0 -0
- data/CONTRIBUTING.md +1 -1
- data/lib/mongo.rb +2 -0
- data/lib/mongo/address.rb +4 -0
- data/lib/mongo/address/validator.rb +99 -0
- data/lib/mongo/auth.rb +7 -2
- data/lib/mongo/auth/user.rb +1 -7
- data/lib/mongo/background_thread.rb +135 -0
- data/lib/mongo/bulk_write/transformable.rb +3 -3
- data/lib/mongo/client.rb +74 -16
- data/lib/mongo/cluster.rb +193 -41
- data/lib/mongo/cluster/periodic_executor.rb +31 -43
- data/lib/mongo/cluster/sdam_flow.rb +26 -3
- data/lib/mongo/cluster/srv_monitor.rb +127 -0
- data/lib/mongo/collection/view/readable.rb +3 -5
- data/lib/mongo/collection/view/writable.rb +3 -3
- data/lib/mongo/cursor/builder/get_more_command.rb +1 -4
- data/lib/mongo/cursor/builder/kill_cursors_command.rb +5 -23
- data/lib/mongo/cursor/builder/op_get_more.rb +2 -2
- data/lib/mongo/cursor/builder/op_kill_cursors.rb +5 -24
- data/lib/mongo/error.rb +1 -0
- data/lib/mongo/error/auth_error.rb +1 -1
- data/lib/mongo/error/connection_check_out_timeout.rb +7 -8
- data/lib/mongo/error/invalid_address.rb +24 -0
- data/lib/mongo/error/notable.rb +2 -2
- data/lib/mongo/error/operation_failure.rb +3 -3
- data/lib/mongo/error/pool_closed_error.rb +11 -4
- data/lib/mongo/event.rb +1 -1
- data/lib/mongo/grid/file.rb +0 -5
- data/lib/mongo/grid/file/chunk.rb +0 -2
- data/lib/mongo/grid/fs_bucket.rb +13 -15
- data/lib/mongo/grid/stream/write.rb +3 -9
- data/lib/mongo/loggable.rb +5 -1
- data/lib/mongo/monitoring.rb +1 -0
- data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +7 -0
- data/lib/mongo/monitoring/event/cmap/connection_checked_in.rb +11 -3
- data/lib/mongo/monitoring/event/cmap/connection_checked_out.rb +11 -3
- data/lib/mongo/monitoring/event/cmap/pool_closed.rb +11 -3
- data/lib/mongo/monitoring/event/cmap/pool_created.rb +12 -3
- data/lib/mongo/monitoring/unified_sdam_log_subscriber.rb +62 -0
- data/lib/mongo/operation/shared/executable.rb +5 -10
- data/lib/mongo/operation/shared/sessions_supported.rb +1 -5
- data/lib/mongo/protocol/get_more.rb +1 -2
- data/lib/mongo/protocol/kill_cursors.rb +13 -6
- data/lib/mongo/protocol/serializers.rb +4 -20
- data/lib/mongo/retryable.rb +9 -34
- data/lib/mongo/semaphore.rb +1 -1
- data/lib/mongo/server.rb +113 -42
- data/lib/mongo/server/connection.rb +12 -5
- data/lib/mongo/server/connection_pool.rb +250 -40
- data/lib/mongo/server/connection_pool/populator.rb +58 -0
- data/lib/mongo/server/description.rb +9 -2
- data/lib/mongo/server/monitor.rb +68 -93
- data/lib/mongo/server/monitor/connection.rb +2 -0
- data/lib/mongo/server_selector/selectable.rb +13 -5
- data/lib/mongo/session.rb +0 -13
- data/lib/mongo/srv.rb +17 -0
- data/lib/mongo/srv/monitor.rb +96 -0
- data/lib/mongo/srv/resolver.rb +130 -0
- data/lib/mongo/srv/result.rb +126 -0
- data/lib/mongo/srv/warning_result.rb +35 -0
- data/lib/mongo/uri.rb +45 -55
- data/lib/mongo/uri/srv_protocol.rb +89 -42
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +3 -4
- data/spec/README.md +6 -1
- data/spec/enterprise_auth/kerberos_spec.rb +7 -6
- data/spec/integration/change_stream_examples_spec.rb +0 -4
- data/spec/integration/client_construction_spec.rb +14 -2
- data/spec/integration/connect_single_rs_name_spec.rb +2 -2
- data/spec/integration/connection_pool_populator_spec.rb +296 -0
- data/spec/integration/connection_spec.rb +31 -22
- data/spec/integration/cursor_reaping_spec.rb +1 -2
- data/spec/integration/docs_examples_spec.rb +0 -4
- data/spec/integration/heartbeat_events_spec.rb +17 -15
- data/spec/integration/reconnect_spec.rb +144 -1
- data/spec/integration/retryable_writes_errors_spec.rb +0 -4
- data/spec/integration/retryable_writes_spec.rb +36 -36
- data/spec/integration/sdam_error_handling_spec.rb +31 -25
- data/spec/integration/sdam_events_spec.rb +2 -6
- data/spec/integration/server_monitor_spec.rb +28 -0
- data/spec/integration/server_selector_spec.rb +7 -5
- data/spec/integration/srv_monitoring_spec.rb +360 -0
- data/spec/integration/step_down_spec.rb +4 -6
- data/spec/lite_spec_helper.rb +22 -0
- data/spec/mongo/address/validator_spec.rb +51 -0
- data/spec/mongo/auth/cr_spec.rb +1 -29
- data/spec/mongo/auth/ldap_spec.rb +1 -29
- data/spec/mongo/auth/scram/conversation_spec.rb +0 -2
- data/spec/mongo/auth/scram/negotiation_spec.rb +1 -1
- data/spec/mongo/auth/scram_spec.rb +1 -29
- data/spec/mongo/auth/user/view_spec.rb +1 -36
- data/spec/mongo/auth/user_spec.rb +0 -12
- data/spec/mongo/auth/x509_spec.rb +1 -29
- data/spec/mongo/bulk_write_spec.rb +2 -2
- data/spec/mongo/client_construction_spec.rb +56 -15
- data/spec/mongo/client_spec.rb +31 -27
- data/spec/mongo/cluster/periodic_executor_spec.rb +16 -0
- data/spec/mongo/cluster/srv_monitor_spec.rb +214 -0
- data/spec/mongo/cluster/topology/replica_set_spec.rb +16 -11
- data/spec/mongo/cluster/topology/sharded_spec.rb +12 -9
- data/spec/mongo/cluster/topology/single_spec.rb +20 -11
- data/spec/mongo/cluster_spec.rb +45 -29
- data/spec/mongo/collection/view/map_reduce_spec.rb +14 -9
- data/spec/mongo/collection/view/readable_spec.rb +0 -16
- data/spec/mongo/collection_spec.rb +0 -44
- data/spec/mongo/cursor/builder/get_more_command_spec.rb +2 -4
- data/spec/mongo/cursor/builder/op_get_more_spec.rb +2 -4
- data/spec/mongo/cursor_spec.rb +27 -7
- data/spec/mongo/monitoring/event/cmap/connection_checked_in_spec.rb +10 -3
- data/spec/mongo/monitoring/event/cmap/connection_checked_out_spec.rb +10 -3
- data/spec/mongo/monitoring/event/cmap/pool_closed_spec.rb +10 -3
- data/spec/mongo/monitoring/event/cmap/pool_created_spec.rb +10 -3
- data/spec/mongo/operation/delete/op_msg_spec.rb +17 -8
- data/spec/mongo/operation/insert/op_msg_spec.rb +50 -35
- data/spec/mongo/operation/update/op_msg_spec.rb +14 -7
- data/spec/mongo/retryable_spec.rb +52 -31
- data/spec/mongo/server/app_metadata_spec.rb +0 -8
- data/spec/mongo/server/connection_auth_spec.rb +5 -2
- data/spec/mongo/server/connection_pool/populator_spec.rb +101 -0
- data/spec/mongo/server/connection_pool_spec.rb +256 -107
- data/spec/mongo/server/connection_spec.rb +22 -33
- data/spec/mongo/server/description_spec.rb +42 -4
- data/spec/mongo/server/monitor/connection_spec.rb +22 -11
- data/spec/mongo/server/monitor_spec.rb +66 -107
- data/spec/mongo/server_spec.rb +82 -60
- data/spec/mongo/session/session_pool_spec.rb +1 -5
- data/spec/mongo/session_spec.rb +0 -4
- data/spec/mongo/socket/ssl_spec.rb +2 -2
- data/spec/mongo/srv/monitor_spec.rb +211 -0
- data/spec/mongo/srv/result_spec.rb +54 -0
- data/spec/mongo/uri/srv_protocol_spec.rb +30 -15
- data/spec/mongo/uri_spec.rb +125 -4
- data/spec/spec_helper.rb +6 -0
- data/spec/spec_tests/auth_spec.rb +39 -0
- data/spec/spec_tests/cmap_spec.rb +55 -8
- data/spec/spec_tests/connection_string_spec.rb +6 -31
- data/spec/spec_tests/data/auth/connection-string.yml +297 -0
- data/spec/spec_tests/data/cmap/pool-checkout-error-closed.yml +4 -1
- data/spec/spec_tests/data/cmap/pool-create-with-options.yml +1 -0
- data/spec/spec_tests/data/command_monitoring/insertMany.yml +1 -1
- data/spec/spec_tests/data/connection_string/invalid-uris.yml +20 -0
- data/spec/spec_tests/data/connection_string/valid-auth.yml +16 -0
- data/spec/spec_tests/data/connection_string/valid-warnings.yml +26 -30
- data/spec/spec_tests/data/transactions/abort.yml +3 -3
- data/spec/spec_tests/data/transactions/error-labels.yml +3 -3
- data/spec/spec_tests/data/transactions_api/callback-retry.yml +3 -3
- data/spec/spec_tests/data/uri_options/auth-options.yml +1 -1
- data/spec/spec_tests/max_staleness_spec.rb +7 -2
- data/spec/spec_tests/retryable_reads_spec.rb +0 -31
- data/spec/spec_tests/sdam_monitoring_spec.rb +12 -12
- data/spec/spec_tests/sdam_spec.rb +4 -7
- data/spec/spec_tests/server_selection_spec.rb +6 -2
- data/spec/spec_tests/transactions_spec.rb +0 -2
- data/spec/spec_tests/uri_options_spec.rb +4 -2
- data/spec/stress/connection_pool_stress_spec.rb +203 -0
- data/spec/stress/connection_pool_timing_spec.rb +181 -0
- data/spec/support/auth.rb +113 -0
- data/spec/support/background_thread_registry.rb +63 -0
- data/spec/support/client_registry.rb +11 -2
- data/spec/support/cluster_config.rb +65 -46
- data/spec/support/cluster_tools.rb +2 -2
- data/spec/support/cmap.rb +13 -14
- data/spec/support/cmap/verifier.rb +4 -5
- data/spec/support/command_monitoring.rb +0 -5
- data/spec/support/common_shortcuts.rb +101 -1
- data/spec/support/constraints.rb +25 -0
- data/spec/support/dns.rb +13 -0
- data/spec/support/event_subscriber.rb +0 -7
- data/spec/support/json_ext_formatter.rb +5 -1
- data/spec/support/lite_constraints.rb +22 -6
- data/spec/support/local_resource_registry.rb +34 -0
- data/spec/support/sdam_monitoring.rb +115 -0
- data/spec/support/spec_config.rb +20 -6
- data/spec/support/spec_setup.rb +2 -2
- data/spec/support/transactions.rb +1 -1
- data/spec/support/transactions/test.rb +1 -1
- data/spec/support/utils.rb +1 -16
- metadata +685 -659
- metadata.gz.sig +0 -0
- data/lib/mongo/event/description_changed.rb +0 -52
- data/spec/integration/bson_symbol_spec.rb +0 -34
- data/spec/integration/crud_spec.rb +0 -45
- data/spec/integration/get_more_spec.rb +0 -32
- data/spec/integration/grid_fs_bucket_spec.rb +0 -48
- data/spec/integration/retryable_errors_spec.rb +0 -265
- data/spec/integration/size_limit_spec.rb~12e1e9c4f... RUBY-2242 Fix zlib compression (#2021) +0 -98
- data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +0 -56
- data/spec/runners/sdam/verifier.rb +0 -88
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7c88c591ffb30fe10134db69727372a4d1c3801a11dce59804ebe53d475d08f
|
4
|
+
data.tar.gz: 16ce4f803cd46df9e0bc6948048fc4c0ea5356d437fbf75b149d38cd872ccca1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb30b7789af0a8816ce50e4b5c3be68e0b0a6f3a0b2da8d4c13a6f6bc8ad826b6a6b505e99df369ed49b24543baa28ff08db655ce3701c1fd2f13b55d4bb9374
|
7
|
+
data.tar.gz: 7490c21d89f2b2c88aaa69d8203973869c409c637c0a212cb2d3cd2783ca258cd6a2df6729375e39894303b39541fd0296faee7c691d1b3e4c3553f6c6169385
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/CONTRIBUTING.md
CHANGED
@@ -23,7 +23,7 @@ Environment
|
|
23
23
|
We recommend using [rbenv](https://github.com/sstephenson/rbenv) to set up
|
24
24
|
the Ruby development and testing environments, though other tools like
|
25
25
|
[RVM](https://rvm.io/) will also work. The driver currently supports
|
26
|
-
MRI
|
26
|
+
MRI 2.3-2.6 and JRuby 9.2.
|
27
27
|
|
28
28
|
A MongoDB cluster is required to run the tests. Setup procedures and
|
29
29
|
recommendations for various clusters, as well as how to configure the
|
data/lib/mongo.rb
CHANGED
@@ -44,6 +44,7 @@ require 'mongo/event'
|
|
44
44
|
require 'mongo/address'
|
45
45
|
require 'mongo/auth'
|
46
46
|
require 'mongo/protocol'
|
47
|
+
require 'mongo/background_thread'
|
47
48
|
require 'mongo/cluster'
|
48
49
|
require 'mongo/cursor'
|
49
50
|
require 'mongo/collection'
|
@@ -56,6 +57,7 @@ require 'mongo/server'
|
|
56
57
|
require 'mongo/server_selector'
|
57
58
|
require 'mongo/session'
|
58
59
|
require 'mongo/socket'
|
60
|
+
require 'mongo/srv'
|
59
61
|
require 'mongo/uri'
|
60
62
|
require 'mongo/version'
|
61
63
|
require 'mongo/write_concern'
|
data/lib/mongo/address.rb
CHANGED
@@ -15,6 +15,7 @@
|
|
15
15
|
require 'mongo/address/ipv4'
|
16
16
|
require 'mongo/address/ipv6'
|
17
17
|
require 'mongo/address/unix'
|
18
|
+
require 'mongo/address/validator'
|
18
19
|
|
19
20
|
module Mongo
|
20
21
|
|
@@ -67,6 +68,9 @@ module Mongo
|
|
67
68
|
#
|
68
69
|
# @since 2.0.0
|
69
70
|
def initialize(seed, options = {})
|
71
|
+
if seed.nil?
|
72
|
+
raise ArgumentError, "address must be not nil"
|
73
|
+
end
|
70
74
|
@seed = seed
|
71
75
|
@host, @port = parse_host_port
|
72
76
|
@options = options
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# Copyright (C) 2017-2019 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the 'License');
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an 'AS IS' BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Mongo
|
16
|
+
|
17
|
+
class Address
|
18
|
+
|
19
|
+
# @api private
|
20
|
+
module Validator
|
21
|
+
|
22
|
+
# Takes an address string in ipv4/ipv6/hostname/socket path format and
|
23
|
+
# validates its format.
|
24
|
+
def validate_address_str!(address_str)
|
25
|
+
case address_str
|
26
|
+
when /\A\[[\d:]+\](?::(\d+))?\z/
|
27
|
+
# ipv6 with optional port
|
28
|
+
if port_str = $1
|
29
|
+
validate_port_str!(port_str)
|
30
|
+
end
|
31
|
+
when /\A\//, /\.sock\z/
|
32
|
+
# Unix socket path.
|
33
|
+
# Spec requires us to validate that the path has no unescaped
|
34
|
+
# slashes, but if this were to be the case, parsing would have
|
35
|
+
# already failed elsewhere because the URI would've been split in
|
36
|
+
# a weird place.
|
37
|
+
# The spec also allows relative socket paths and requires that
|
38
|
+
# socket paths end in ".sock". We accept all paths but special case
|
39
|
+
# the .sock extension to avoid relative paths falling into the
|
40
|
+
# host:port case below.
|
41
|
+
when /[\/\[\]]/
|
42
|
+
# Not a host:port nor an ipv4 address with optional port.
|
43
|
+
# Possibly botched ipv6 address with e.g. port delimiter present and
|
44
|
+
# port missing, or extra junk before or after.
|
45
|
+
raise Error::InvalidAddress,
|
46
|
+
"Invalid hostname: #{address_str}"
|
47
|
+
when /:.*:/m
|
48
|
+
raise Error::InvalidAddress,
|
49
|
+
"Multiple port delimiters are not allowed: #{address_str}"
|
50
|
+
else
|
51
|
+
# host:port or ipv4 address with optional port number
|
52
|
+
host, port = address_str.split(':')
|
53
|
+
if host.empty?
|
54
|
+
raise Error::InvalidAddress, "Host is empty: #{address_str}"
|
55
|
+
end
|
56
|
+
|
57
|
+
validate_hostname!(host)
|
58
|
+
|
59
|
+
if port && port.empty?
|
60
|
+
raise Error::InvalidAddress, "Port is empty: #{address_str}"
|
61
|
+
end
|
62
|
+
|
63
|
+
validate_port_str!(port)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
# Validates format of the hostname, in particular for further use as
|
70
|
+
# the origin in same origin verification.
|
71
|
+
#
|
72
|
+
# The hostname must have been normalized to remove the trailing dot if
|
73
|
+
# it was obtained from a DNS record. This method prohibits trailing dots.
|
74
|
+
def validate_hostname!(host)
|
75
|
+
# Since we are performing same origin verification during SRV
|
76
|
+
# processing, prohibit leading dots in hostnames, trailing dots
|
77
|
+
# and runs of multiple dots. DNS resolution of SRV records yields
|
78
|
+
# hostnames with trailing dots, those trailing dots are removed
|
79
|
+
# during normalization process prior to validation.
|
80
|
+
if host.start_with?('.')
|
81
|
+
raise Error::InvalidAddress, "Hostname cannot start with a dot: #{host}"
|
82
|
+
end
|
83
|
+
if host.end_with?('.')
|
84
|
+
raise Error::InvalidAddress, "Hostname cannot end with a dot: #{host}"
|
85
|
+
end
|
86
|
+
if host.include?('..')
|
87
|
+
raise Error::InvalidAddress, "Runs of multiple dots are not allowed in hostname: #{host}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def validate_port_str!(port)
|
92
|
+
unless port.nil? || (port.length > 0 && port.to_i > 0 && port.to_i <= 65535)
|
93
|
+
raise Error::InvalidAddress,
|
94
|
+
"Invalid port: #{port}. Port must be an integer greater than 0 and less than 65536"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/mongo/auth.rb
CHANGED
@@ -70,10 +70,15 @@ module Mongo
|
|
70
70
|
SOURCES[mechanism].new(user)
|
71
71
|
end
|
72
72
|
|
73
|
+
# Raised when trying to authorize with an invalid configuration
|
74
|
+
#
|
75
|
+
# @since 2.11.0
|
76
|
+
class InvalidConfiguration < Mongo::Error::AuthError; end
|
77
|
+
|
73
78
|
# Raised when trying to get an invalid authorization mechanism.
|
74
79
|
#
|
75
80
|
# @since 2.0.0
|
76
|
-
class InvalidMechanism <
|
81
|
+
class InvalidMechanism < InvalidConfiguration
|
77
82
|
|
78
83
|
# Instantiate the new error.
|
79
84
|
#
|
@@ -94,7 +99,7 @@ module Mongo
|
|
94
99
|
# Raised when a user is not authorized on a database.
|
95
100
|
#
|
96
101
|
# @since 2.0.0
|
97
|
-
class Unauthorized <
|
102
|
+
class Unauthorized < Mongo::Error::AuthError
|
98
103
|
|
99
104
|
# Instantiate the new error.
|
100
105
|
#
|
data/lib/mongo/auth/user.rb
CHANGED
@@ -151,8 +151,6 @@ module Mongo
|
|
151
151
|
# authorized for.
|
152
152
|
# @option options [ String ] :user The user name.
|
153
153
|
# @option options [ String ] :password The user's password.
|
154
|
-
# @option options [ String ] :pwd Legacy option for the user's password.
|
155
|
-
# If :password and :pwd are both specified, :password takes precedence.
|
156
154
|
# @option options [ Symbol ] :auth_mech The authorization mechanism.
|
157
155
|
# @option options [ Array<String>, Array<Hash> ] roles The user roles.
|
158
156
|
# @option options [ String ] :client_key The user's client key cached from a previous
|
@@ -198,11 +196,7 @@ module Mongo
|
|
198
196
|
#
|
199
197
|
# @since 2.0.0
|
200
198
|
def spec
|
201
|
-
{roles: roles}
|
202
|
-
if password
|
203
|
-
spec[:pwd] = password
|
204
|
-
end
|
205
|
-
end
|
199
|
+
{ pwd: password, roles: roles }
|
206
200
|
end
|
207
201
|
|
208
202
|
private
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# Copyright (C) 2019 MongoDB, Inc.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Mongo
|
16
|
+
|
17
|
+
# The run!, running? and stop! methods used to be part of the public API
|
18
|
+
# in some of the classes which now include this module. Therefore these
|
19
|
+
# methods must be considered part of the driver's public API for backwards
|
20
|
+
# compatibility reasons. However using these methods outside of the driver
|
21
|
+
# is deprecated.
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
module BackgroundThread
|
25
|
+
include Loggable
|
26
|
+
|
27
|
+
# Start the background thread.
|
28
|
+
#
|
29
|
+
# If the thread is already running, this method does nothing.
|
30
|
+
#
|
31
|
+
# @api public for backwards compatibility only
|
32
|
+
def run!
|
33
|
+
if running?
|
34
|
+
@thread
|
35
|
+
else
|
36
|
+
start!
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# @api public for backwards compatibility only
|
41
|
+
def running?
|
42
|
+
if @thread
|
43
|
+
@thread.alive?
|
44
|
+
else
|
45
|
+
false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Stop the background thread and wait for to terminate for a reasonable
|
50
|
+
# amount of time.
|
51
|
+
#
|
52
|
+
# @return [ true | false ] Whether the thread was terminated.
|
53
|
+
#
|
54
|
+
# @api public for backwards compatibility only
|
55
|
+
def stop!
|
56
|
+
# If the thread was not started, there is nothing to stop.
|
57
|
+
#
|
58
|
+
# Classes including this module may want to perform additional
|
59
|
+
# cleanup, which they can do by overriding this method.
|
60
|
+
return true unless @thread
|
61
|
+
|
62
|
+
# Background threads generally perform operations in a loop.
|
63
|
+
# This flag is meant to be checked on each iteration of the
|
64
|
+
# working loops and the thread should stop working when this flag
|
65
|
+
# is set.
|
66
|
+
@stop_requested = true
|
67
|
+
|
68
|
+
# Besides setting the flag, a particular class may have additional
|
69
|
+
# ways of signaling the background thread to either stop working or
|
70
|
+
# wake up to check the stop flag, for example, setting a semaphore.
|
71
|
+
# This can be accomplished by providing the pre_stop method.
|
72
|
+
pre_stop
|
73
|
+
|
74
|
+
# Now we have requested the graceful termination, and we could wait
|
75
|
+
# for the thread to exit on its own accord. A future version of the
|
76
|
+
# driver may allow a certain amount of time for the thread to quit.
|
77
|
+
# For now, we additionally use the Ruby machinery to request the thread
|
78
|
+
# be terminated, and do so immediately.
|
79
|
+
#
|
80
|
+
# Note that this may cause the background thread to terminate in
|
81
|
+
# the middle of an operation.
|
82
|
+
@thread.kill
|
83
|
+
|
84
|
+
# Wait for the thread to die. This is important in order to reliably
|
85
|
+
# clean up resources like connections knowing that no background
|
86
|
+
# thread will reconnect because it is still working.
|
87
|
+
#
|
88
|
+
# However, we do not want to wait indefinitely because in theory
|
89
|
+
# a background thread could be performing, say, network I/O and if
|
90
|
+
# the network is no longer available that could take a long time.
|
91
|
+
start_time = Time.now
|
92
|
+
([0.1, 0.15] + [0.2] * 5 + [0.3] * 20).each do |interval|
|
93
|
+
begin
|
94
|
+
Timeout.timeout(interval) do
|
95
|
+
@thread.join
|
96
|
+
end
|
97
|
+
break
|
98
|
+
rescue Timeout::Error
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Some driver objects can be reconnected, for backwards compatibiilty
|
103
|
+
# reasons. Clear the thread instance variable to support this cleanly.
|
104
|
+
if @thread.alive?
|
105
|
+
log_warn("Failed to stop background thread in #{self} in #{(Time.now - start_time).to_i} seconds")
|
106
|
+
false
|
107
|
+
else
|
108
|
+
@thread = nil
|
109
|
+
true
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
# @return [ Thread ] The created Thread instance.
|
116
|
+
def start!
|
117
|
+
@thread = Thread.new do
|
118
|
+
catch(:done) do
|
119
|
+
until @stop_requested
|
120
|
+
do_work
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Override this method to do the work in the background thread.
|
127
|
+
def do_work
|
128
|
+
end
|
129
|
+
|
130
|
+
# Override this method to perform additional signaling for the background
|
131
|
+
# thread to stop.
|
132
|
+
def pre_stop
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -92,7 +92,7 @@ module Mongo
|
|
92
92
|
Operation::U => doc[:replacement],
|
93
93
|
}.tap do |d|
|
94
94
|
if doc[:upsert]
|
95
|
-
d[
|
95
|
+
d[:upsert] = true
|
96
96
|
end
|
97
97
|
d[Operation::COLLATION] = doc[:collation] if doc[:collation]
|
98
98
|
end
|
@@ -108,7 +108,7 @@ module Mongo
|
|
108
108
|
Operation::MULTI => true,
|
109
109
|
}.tap do |d|
|
110
110
|
if doc[:upsert]
|
111
|
-
d[
|
111
|
+
d[:upsert] = true
|
112
112
|
end
|
113
113
|
d[Operation::COLLATION] = doc[:collation] if doc[:collation]
|
114
114
|
d[Operation::ARRAY_FILTERS] = doc[:array_filters] if doc[:array_filters]
|
@@ -124,7 +124,7 @@ module Mongo
|
|
124
124
|
Operation::U => doc[:update],
|
125
125
|
}.tap do |d|
|
126
126
|
if doc[:upsert]
|
127
|
-
d[
|
127
|
+
d[:upsert] = true
|
128
128
|
end
|
129
129
|
d[Operation::COLLATION] = doc[:collation] if doc[:collation]
|
130
130
|
d[Operation::ARRAY_FILTERS] = doc[:array_filters] if doc[:array_filters]
|
data/lib/mongo/client.rb
CHANGED
@@ -62,6 +62,7 @@ module Mongo
|
|
62
62
|
:id_generator,
|
63
63
|
:local_threshold,
|
64
64
|
:logger,
|
65
|
+
:log_prefix,
|
65
66
|
:max_idle_time,
|
66
67
|
:max_pool_size,
|
67
68
|
:max_read_retries,
|
@@ -75,6 +76,7 @@ module Mongo
|
|
75
76
|
:read_concern,
|
76
77
|
:read_retry_interval,
|
77
78
|
:replica_set,
|
79
|
+
:resolv_options,
|
78
80
|
:retry_reads,
|
79
81
|
:retry_writes,
|
80
82
|
:scan,
|
@@ -215,13 +217,16 @@ module Mongo
|
|
215
217
|
# @option options [ Float ] :connect_timeout The timeout, in seconds, to
|
216
218
|
# attempt a connection.
|
217
219
|
# @option options [ String ] :database The database to connect to.
|
218
|
-
# @option options [ Float ] :heartbeat_frequency The
|
219
|
-
# the server monitor to refresh
|
220
|
+
# @option options [ Float ] :heartbeat_frequency The interval, in seconds,
|
221
|
+
# for the server monitor to refresh its description via ismaster.
|
220
222
|
# @option options [ Object ] :id_generator A custom object to generate ids
|
221
223
|
# for documents. Must respond to #generate.
|
222
224
|
# @option options [ Integer ] :local_threshold The local threshold boundary
|
223
225
|
# in seconds for selecting a near server for an operation.
|
224
|
-
# @option options [ Logger ] :logger A custom logger
|
226
|
+
# @option options [ Logger ] :logger A custom logger to use.
|
227
|
+
# @option options [ String ] :log_prefix A custom log prefix to use when
|
228
|
+
# logging. This option is experimental and subject to change in a future
|
229
|
+
# version of the driver.
|
225
230
|
# @option options [ Integer ] :max_idle_time The maximum seconds a socket can remain idle
|
226
231
|
# since it has been checked in to the pool.
|
227
232
|
# @option options [ Integer ] :max_pool_size The maximum size of the
|
@@ -361,6 +366,8 @@ module Mongo
|
|
361
366
|
# Can be :w => Integer|String, :fsync => Boolean, :j => Boolean.
|
362
367
|
# @option options [ Integer ] :zlib_compression_level The Zlib compression level to use, if using compression.
|
363
368
|
# See Ruby's Zlib module for valid levels.
|
369
|
+
# @option options [ Hash ] :resolv_options For internal driver use only.
|
370
|
+
# Options to pass through to Resolv::DNS constructor for SRV lookups.
|
364
371
|
#
|
365
372
|
# @since 2.0.0
|
366
373
|
def initialize(addresses_or_uri, options = nil)
|
@@ -370,8 +377,14 @@ module Mongo
|
|
370
377
|
options = {}
|
371
378
|
end
|
372
379
|
|
380
|
+
srv_uri = nil
|
373
381
|
if addresses_or_uri.is_a?(::String)
|
374
382
|
uri = URI.get(addresses_or_uri, options)
|
383
|
+
if uri.is_a?(URI::SRVProtocol)
|
384
|
+
# If the URI is an SRV URI, note this so that we can start
|
385
|
+
# SRV polling if the topology is a sharded cluster.
|
386
|
+
srv_uri = uri
|
387
|
+
end
|
375
388
|
addresses = uri.servers
|
376
389
|
uri_options = uri.client_options.dup
|
377
390
|
# Special handing for :write and :write_concern: allow client Ruby
|
@@ -382,8 +395,10 @@ module Mongo
|
|
382
395
|
uri_options.delete(:write_concern)
|
383
396
|
end
|
384
397
|
options = uri_options.merge(options)
|
398
|
+
@srv_records = uri.srv_records
|
385
399
|
else
|
386
400
|
addresses = addresses_or_uri
|
401
|
+
@srv_records = nil
|
387
402
|
end
|
388
403
|
|
389
404
|
unless options[:retry_reads] == false
|
@@ -407,6 +422,7 @@ module Mongo
|
|
407
422
|
=end
|
408
423
|
@options.freeze
|
409
424
|
validate_options!
|
425
|
+
validate_authentication_options!
|
410
426
|
|
411
427
|
@database = Database.new(self, @options[:database], @options)
|
412
428
|
|
@@ -418,8 +434,7 @@ module Mongo
|
|
418
434
|
sdam_proc.call(self)
|
419
435
|
end
|
420
436
|
|
421
|
-
@
|
422
|
-
@cluster = Cluster.new(addresses, @monitoring, cluster_options)
|
437
|
+
@cluster = Cluster.new(addresses, @monitoring, cluster_options.merge(srv_uri: srv_uri))
|
423
438
|
|
424
439
|
# Unset monitoring, it will be taken out of cluster from now on
|
425
440
|
remove_instance_variable('@monitoring')
|
@@ -435,7 +450,6 @@ module Mongo
|
|
435
450
|
options.reject do |key, value|
|
436
451
|
CRUD_OPTIONS.include?(key.to_sym)
|
437
452
|
end.merge(
|
438
|
-
server_selection_semaphore: @server_selection_semaphore,
|
439
453
|
# but need to put the database back in for auth...
|
440
454
|
database: options[:database],
|
441
455
|
|
@@ -444,7 +458,14 @@ module Mongo
|
|
444
458
|
# applications should read these values from client, not from cluster
|
445
459
|
max_read_retries: options[:max_read_retries],
|
446
460
|
read_retry_interval: options[:read_retry_interval],
|
447
|
-
)
|
461
|
+
).tap do |options|
|
462
|
+
# If the client has a cluster already, forward srv_uri to the new
|
463
|
+
# cluster to maintain SRV monitoring. If the client is brand new,
|
464
|
+
# its constructor sets srv_uri manually.
|
465
|
+
if cluster
|
466
|
+
options.update(srv_uri: cluster.options[:srv_uri])
|
467
|
+
end
|
468
|
+
end
|
448
469
|
end
|
449
470
|
|
450
471
|
# Get the maximum number of times the client can retry a read operation
|
@@ -616,6 +637,7 @@ module Mongo
|
|
616
637
|
options.update(opts)
|
617
638
|
@options = options.freeze
|
618
639
|
validate_options!
|
640
|
+
validate_authentication_options!
|
619
641
|
end
|
620
642
|
end
|
621
643
|
|
@@ -647,17 +669,11 @@ module Mongo
|
|
647
669
|
|
648
670
|
# Close all connections.
|
649
671
|
#
|
650
|
-
# @example Disconnect the client.
|
651
|
-
# client.close
|
652
|
-
#
|
653
|
-
# @param [ Boolean ] wait Whether to wait for background threads to
|
654
|
-
# finish running.
|
655
|
-
#
|
656
672
|
# @return [ true ] Always true.
|
657
673
|
#
|
658
674
|
# @since 2.1.0
|
659
|
-
def close
|
660
|
-
@cluster.disconnect!
|
675
|
+
def close
|
676
|
+
@cluster.disconnect!
|
661
677
|
true
|
662
678
|
end
|
663
679
|
|
@@ -857,7 +873,7 @@ module Mongo
|
|
857
873
|
end
|
858
874
|
|
859
875
|
# Validates all options after they are set on the client.
|
860
|
-
# This method is intended to catch combinations of options which
|
876
|
+
# This method is intended to catch combinations of options which are
|
861
877
|
# not allowed.
|
862
878
|
def validate_options!
|
863
879
|
if options[:write] && options[:write_concern] && options[:write] != options[:write_concern]
|
@@ -865,6 +881,48 @@ module Mongo
|
|
865
881
|
end
|
866
882
|
end
|
867
883
|
|
884
|
+
# Validates all authentication-related options after they are set on the client
|
885
|
+
# This method is intended to catch combinations of options which are not allowed
|
886
|
+
def validate_authentication_options!
|
887
|
+
auth_mech = options[:auth_mech]
|
888
|
+
user = options[:user]
|
889
|
+
password = options[:password]
|
890
|
+
auth_source = options[:auth_source]
|
891
|
+
mech_properties = options[:auth_mech_properties]
|
892
|
+
|
893
|
+
if auth_mech.nil?
|
894
|
+
if user && user.empty?
|
895
|
+
raise Mongo::Auth::InvalidConfiguration.new('empty username is not supported for default auth mechanism')
|
896
|
+
end
|
897
|
+
|
898
|
+
return
|
899
|
+
end
|
900
|
+
|
901
|
+
if !Mongo::Auth::SOURCES.key?(auth_mech)
|
902
|
+
raise Mongo::Auth::InvalidMechanism.new(auth_mech)
|
903
|
+
end
|
904
|
+
|
905
|
+
if user.nil? && auth_mech != :mongodb_x509
|
906
|
+
raise Mongo::Auth::InvalidConfiguration.new("user is required for mechanism #{auth_mech}")
|
907
|
+
end
|
908
|
+
|
909
|
+
if password.nil? && ![:gssapi, :mongodb_x509].include?(auth_mech)
|
910
|
+
raise Mongo::Auth::InvalidConfiguration.new("password is required for mechanism #{auth_mech}")
|
911
|
+
end
|
912
|
+
|
913
|
+
if password && auth_mech == :mongodb_x509
|
914
|
+
raise Mongo::Auth::InvalidConfiguration.new('password is not supported for mongodb_x509')
|
915
|
+
end
|
916
|
+
|
917
|
+
if ![:external, nil].include?(auth_source) && [:gssapi, :mongodb_x509].include?(auth_mech)
|
918
|
+
raise Mongo::Auth::InvalidConfiguration.new("#{auth_source} is an invalid auth source for #{auth_mech}; valid options are $external and nil")
|
919
|
+
end
|
920
|
+
|
921
|
+
if mech_properties && auth_mech != :gssapi
|
922
|
+
raise Mongo::Auth::InvalidConfiguration.new("mechanism_properties are not supported for #{auth_mech}")
|
923
|
+
end
|
924
|
+
end
|
925
|
+
|
868
926
|
def valid_compressors(compressors)
|
869
927
|
compressors.select do |compressor|
|
870
928
|
if !VALID_COMPRESSORS.include?(compressor)
|