mongo 2.11.0.rc0 → 2.11.0
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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/Rakefile +2 -0
- data/lib/mongo/auth.rb +11 -2
- data/lib/mongo/auth/cr/conversation.rb +1 -1
- data/lib/mongo/auth/ldap/conversation.rb +1 -1
- data/lib/mongo/auth/scram/conversation.rb +4 -1
- data/lib/mongo/auth/user.rb +15 -1
- data/lib/mongo/auth/user/view.rb +10 -4
- data/lib/mongo/auth/x509.rb +11 -1
- data/lib/mongo/auth/x509/conversation.rb +15 -6
- data/lib/mongo/background_thread.rb +28 -13
- data/lib/mongo/client.rb +23 -15
- data/lib/mongo/collection/view/change_stream.rb +5 -1
- data/lib/mongo/collection/view/readable.rb +5 -2
- data/lib/mongo/collection/view/writable.rb +3 -1
- data/lib/mongo/cursor/builder/get_more_command.rb +4 -1
- data/lib/mongo/cursor/builder/kill_cursors_command.rb +16 -5
- data/lib/mongo/cursor/builder/op_get_more.rb +2 -2
- data/lib/mongo/cursor/builder/op_kill_cursors.rb +17 -5
- data/lib/mongo/error/operation_failure.rb +3 -3
- data/lib/mongo/monitoring/command_log_subscriber.rb +5 -3
- data/lib/mongo/monitoring/event/command_started.rb +13 -3
- data/lib/mongo/monitoring/publishable.rb +4 -2
- data/lib/mongo/operation/create_user/command.rb +1 -0
- data/lib/mongo/operation/remove_user/command.rb +1 -0
- data/lib/mongo/operation/update_user/command.rb +1 -0
- data/lib/mongo/protocol/get_more.rb +2 -1
- data/lib/mongo/protocol/kill_cursors.rb +6 -13
- data/lib/mongo/protocol/serializers.rb +10 -4
- data/lib/mongo/retryable.rb +1 -1
- data/lib/mongo/server/connection.rb +6 -2
- data/lib/mongo/server/connection_base.rb +2 -1
- data/lib/mongo/server/monitor.rb +1 -1
- data/lib/mongo/server/pending_connection.rb +6 -0
- data/lib/mongo/socket/ssl.rb +1 -1
- data/lib/mongo/uri.rb +5 -41
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +11 -2
- data/spec/README.md +105 -9
- data/spec/USERS.md +72 -0
- data/spec/integration/auth_spec.rb +20 -6
- data/spec/integration/client_construction_spec.rb +3 -1
- data/spec/integration/client_options_spec.rb +437 -0
- data/spec/integration/command_monitoring_spec.rb +4 -1
- data/spec/integration/connection_pool_populator_spec.rb +4 -0
- data/spec/integration/connection_spec.rb +4 -2
- data/spec/integration/cursor_reaping_spec.rb +1 -1
- data/spec/integration/get_more_spec.rb +32 -0
- data/spec/integration/retryable_errors_spec.rb +99 -0
- data/spec/integration/retryable_writes_errors_spec.rb +11 -10
- data/spec/lite_spec_helper.rb +2 -1
- data/spec/mongo/auth/scram_spec.rb +1 -0
- data/spec/mongo/auth/user/view_spec.rb +102 -1
- data/spec/mongo/auth/user_spec.rb +56 -15
- data/spec/mongo/auth/x509_spec.rb +31 -1
- data/spec/mongo/bulk_write_spec.rb +2 -2
- data/spec/mongo/collection/view/change_stream_spec.rb +2 -2
- data/spec/mongo/collection/view/readable_spec.rb +8 -4
- data/spec/mongo/cursor/builder/get_more_command_spec.rb +4 -2
- data/spec/mongo/cursor/builder/op_get_more_spec.rb +4 -2
- data/spec/mongo/cursor_spec.rb +3 -3
- data/spec/mongo/retryable_spec.rb +31 -52
- data/spec/mongo/server/connection_auth_spec.rb +3 -0
- data/spec/mongo/server/connection_pool_spec.rb +4 -0
- data/spec/mongo/server/connection_spec.rb +12 -4
- data/spec/mongo/server/monitor_spec.rb +19 -1
- data/spec/mongo/socket/ssl_spec.rb +1 -1
- data/spec/mongo/uri/srv_protocol_spec.rb +0 -13
- data/spec/mongo/uri_option_parsing_spec.rb +0 -8
- data/spec/mongo/uri_spec.rb +6 -20
- data/spec/runners/connection_string.rb +116 -0
- data/spec/runners/read_write_concern_document.rb +67 -0
- data/spec/spec_tests/change_streams_spec.rb +17 -2
- data/spec/spec_tests/connection_string_spec.rb +2 -59
- data/spec/spec_tests/data/change_streams/change-streams-errors.yml +3 -3
- data/spec/spec_tests/data/change_streams/change-streams.yml +88 -20
- data/spec/spec_tests/data/cmap/connection-must-have-id.yml +6 -0
- data/spec/spec_tests/data/cmap/connection-must-order-ids.yml +6 -0
- data/spec/spec_tests/data/cmap/pool-checkin-destroy-closed.yml +3 -0
- data/spec/spec_tests/data/cmap/pool-checkin-destroy-stale.yml +3 -0
- data/spec/spec_tests/data/cmap/pool-checkin-make-available.yml +3 -0
- data/spec/spec_tests/data/cmap/pool-checkin.yml +1 -0
- data/spec/spec_tests/data/cmap/pool-checkout-connection.yml +2 -0
- data/spec/spec_tests/data/cmap/pool-checkout-error-closed.yml +5 -0
- data/spec/spec_tests/data/cmap/pool-checkout-multiple.yml +3 -0
- data/spec/spec_tests/data/cmap/pool-checkout-no-idle.yml +4 -0
- data/spec/spec_tests/data/cmap/pool-checkout-no-stale.yml +4 -0
- data/spec/spec_tests/data/cmap/pool-close-destroy-conns.yml +2 -0
- data/spec/spec_tests/data/cmap/pool-create-max-size.yml +15 -0
- data/spec/spec_tests/data/cmap/pool-create-min-size.yml +4 -0
- data/spec/spec_tests/data/cmap/wait-queue-fairness.yml +31 -1
- data/spec/spec_tests/data/cmap/wait-queue-timeout.yml +5 -0
- data/spec/spec_tests/data/read_write_concern/connection-string/read-concern.yml +32 -0
- data/spec/spec_tests/data/read_write_concern/connection-string/write-concern.yml +82 -0
- data/spec/spec_tests/data/read_write_concern/document/read-concern.yml +37 -0
- data/spec/spec_tests/data/read_write_concern/document/write-concern.yml +100 -0
- data/spec/spec_tests/data/retryable_reads/aggregate-merge.yml +39 -0
- data/spec/spec_tests/data/retryable_reads/aggregate-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch-serverErrors.yml +2 -2
- data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch-serverErrors.yml +2 -2
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch-serverErrors.yml +2 -2
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/count-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/countDocuments-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/distinct-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/find-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/findOne-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/gridfs-download-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/gridfs-downloadByName-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/listCollectionNames-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/listCollectionObjects-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/listCollections-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/listDatabaseNames-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/listDatabaseObjects-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/listDatabases-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/listIndexNames-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/listIndexes-serverErrors.yml +1 -1
- data/spec/spec_tests/data/transactions/read-concern.yml +6 -6
- data/spec/spec_tests/data/transactions/transaction-options-repl.yml +117 -0
- data/spec/spec_tests/data/transactions/transaction-options.yml +14 -121
- data/spec/spec_tests/data/transactions/write-concern.yml +3 -0
- data/spec/spec_tests/data/transactions_api/transaction-options.yml +11 -12
- data/spec/spec_tests/dns_seedlist_discovery_spec.rb +17 -7
- data/spec/spec_tests/read_write_concern_connection_string_spec.rb +8 -0
- data/spec/spec_tests/read_write_concern_document_spec.rb +74 -0
- data/spec/spec_tests/retryable_reads_spec.rb +32 -1
- data/spec/spec_tests/uri_options_spec.rb +4 -2
- data/spec/support/auth.rb +5 -14
- data/spec/support/certificates/client-x509.crt +78 -0
- data/spec/support/certificates/client-x509.key +27 -0
- data/spec/support/certificates/client-x509.pem +105 -0
- data/spec/support/change_streams.rb +8 -11
- data/spec/support/client_registry.rb +26 -12
- data/spec/support/cluster_tools.rb +2 -2
- data/spec/support/cmap.rb +11 -7
- data/spec/support/command_monitoring.rb +8 -8
- data/spec/support/connection_string.rb +56 -28
- data/spec/support/constraints.rb +8 -0
- data/spec/support/crud/spec.rb +5 -8
- data/spec/support/event_subscriber.rb +7 -0
- data/spec/support/gridfs.rb +4 -7
- data/spec/support/server_discovery_and_monitoring.rb +3 -8
- data/spec/support/server_selection.rb +4 -9
- data/spec/support/server_selection_rtt.rb +4 -7
- data/spec/support/spec_config.rb +47 -19
- data/spec/support/spec_setup.rb +5 -0
- data/spec/support/utils.rb +46 -8
- metadata +637 -597
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d27047092172489df2f36b02e09050990a7aae2685a055bf4a30d33a43b86325
|
4
|
+
data.tar.gz: 0f14e016a1dbae9ccda55d77927a773d58a10967b959b9480b052c2df9410386
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3cf2e4bfd5860003b7131c72fae1b58a0a56906a73d67e9e08c465cd5cf0b79f99af431e55597733f3baf9d68a9617cec47647d4bb7b9c8e84eedeeff96509b9
|
7
|
+
data.tar.gz: 190be385cbcfdae0293448281010b8d6c4ca785b37236fe57362921eaeb7cfdb5115dd0159e51622946b97170fa105a375fd0a73ceb4600b268e599aa687dcf1
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/Rakefile
CHANGED
@@ -29,6 +29,7 @@ namespace :spec do
|
|
29
29
|
task :prepare do
|
30
30
|
$: << File.join(File.dirname(__FILE__), 'spec')
|
31
31
|
|
32
|
+
require 'support/utils'
|
32
33
|
require 'support/spec_setup'
|
33
34
|
SpecSetup.new.run
|
34
35
|
end
|
@@ -40,6 +41,7 @@ namespace :spec do
|
|
40
41
|
# Since this task is usually used for troubleshooting of test suite
|
41
42
|
# configuration, leave driver log level at the default of debug to
|
42
43
|
# have connection diagnostics printed during handshakes and such.
|
44
|
+
require 'support/utils'
|
43
45
|
require 'support/spec_config'
|
44
46
|
require 'support/client_registry'
|
45
47
|
SpecConfig.instance.print_summary
|
data/lib/mongo/auth.rb
CHANGED
@@ -109,9 +109,10 @@ module Mongo
|
|
109
109
|
# @param [ Mongo::Auth::User ] user The unauthorized user.
|
110
110
|
# @param [ String ] used_mechanism Auth mechanism actually used for
|
111
111
|
# authentication. This is a full string like SCRAM-SHA-256.
|
112
|
+
# @param [ String ] message The error message returned by the server.
|
112
113
|
#
|
113
114
|
# @since 2.0.0
|
114
|
-
def initialize(user, used_mechanism
|
115
|
+
def initialize(user, used_mechanism: nil, message: nil)
|
115
116
|
specified_mechanism = if user.mechanism
|
116
117
|
" (mechanism: #{user.mechanism})"
|
117
118
|
else
|
@@ -122,7 +123,15 @@ module Mongo
|
|
122
123
|
else
|
123
124
|
''
|
124
125
|
end
|
125
|
-
|
126
|
+
used_user = if user.mechanism == :mongodb_x509
|
127
|
+
'Client certificate'
|
128
|
+
else
|
129
|
+
"User #{user.name}"
|
130
|
+
end
|
131
|
+
msg = "#{used_user}#{specified_mechanism} is not authorized to access #{user.database} (auth source: #{user.auth_source})#{used_mechanism}"
|
132
|
+
if message
|
133
|
+
msg += ': ' + message
|
134
|
+
end
|
126
135
|
super(msg)
|
127
136
|
end
|
128
137
|
end
|
@@ -131,7 +131,7 @@ module Mongo
|
|
131
131
|
|
132
132
|
def validate!(reply)
|
133
133
|
if reply.documents[0][Operation::Result::OK] != 1
|
134
|
-
raise Unauthorized.new(user, MECHANISM)
|
134
|
+
raise Unauthorized.new(user, used_mechanism: MECHANISM)
|
135
135
|
end
|
136
136
|
@nonce = reply.documents[0][Auth::NONCE]
|
137
137
|
@reply = reply
|
@@ -519,7 +519,10 @@ module Mongo
|
|
519
519
|
|
520
520
|
def validate!(reply)
|
521
521
|
if reply.documents[0][Operation::Result::OK] != 1
|
522
|
-
raise Unauthorized.new(user,
|
522
|
+
raise Unauthorized.new(user,
|
523
|
+
used_mechanism: full_mechanism,
|
524
|
+
message: reply.documents[0]['errmsg'],
|
525
|
+
)
|
523
526
|
end
|
524
527
|
@reply = reply
|
525
528
|
end
|
data/lib/mongo/auth/user.rb
CHANGED
@@ -159,7 +159,7 @@ module Mongo
|
|
159
159
|
# @since 2.0.0
|
160
160
|
def initialize(options)
|
161
161
|
@database = options[:database] || Database::ADMIN
|
162
|
-
@auth_source = options[:auth_source] ||
|
162
|
+
@auth_source = options[:auth_source] || self.class.default_auth_source(options)
|
163
163
|
@name = options[:user]
|
164
164
|
@password = options[:password] || options[:pwd]
|
165
165
|
@mechanism = options[:auth_mech]
|
@@ -205,6 +205,20 @@ module Mongo
|
|
205
205
|
#
|
206
206
|
# @return [ String ] The client key for the user.
|
207
207
|
attr_reader :client_key
|
208
|
+
|
209
|
+
# Generate default auth source based on the URI and options
|
210
|
+
#
|
211
|
+
# @api private
|
212
|
+
def self.default_auth_source(options)
|
213
|
+
case options[:auth_mech]
|
214
|
+
when :gssapi, :mongodb_x509
|
215
|
+
'$external'
|
216
|
+
when :plain
|
217
|
+
options[:database] || '$external'
|
218
|
+
else
|
219
|
+
options[:database] || Database::ADMIN
|
220
|
+
end
|
221
|
+
end
|
208
222
|
end
|
209
223
|
end
|
210
224
|
end
|
data/lib/mongo/auth/user/view.rb
CHANGED
@@ -37,6 +37,7 @@ module Mongo
|
|
37
37
|
# @param [ Hash ] options The user options.
|
38
38
|
#
|
39
39
|
# @option options [ Session ] :session The session to use for the operation.
|
40
|
+
# @option options [ Hash ] :write_concern The write concern options.
|
40
41
|
#
|
41
42
|
# @return [ Result ] The command response.
|
42
43
|
#
|
@@ -47,7 +48,8 @@ module Mongo
|
|
47
48
|
Operation::CreateUser.new(
|
48
49
|
user: user,
|
49
50
|
db_name: database.name,
|
50
|
-
session: session
|
51
|
+
session: session,
|
52
|
+
write_concern: options[:write_concern] && WriteConcern.get(options[:write_concern]),
|
51
53
|
).execute(next_primary(nil, session))
|
52
54
|
end
|
53
55
|
end
|
@@ -73,6 +75,7 @@ module Mongo
|
|
73
75
|
# @param [ Hash ] options The options for the remove operation.
|
74
76
|
#
|
75
77
|
# @option options [ Session ] :session The session to use for the operation.
|
78
|
+
# @option options [ Hash ] :write_concern The write concern options.
|
76
79
|
#
|
77
80
|
# @return [ Result ] The command response.
|
78
81
|
#
|
@@ -82,7 +85,8 @@ module Mongo
|
|
82
85
|
Operation::RemoveUser.new(
|
83
86
|
user_name: name,
|
84
87
|
db_name: database.name,
|
85
|
-
session: session
|
88
|
+
session: session,
|
89
|
+
write_concern: options[:write_concern] && WriteConcern.get(options[:write_concern]),
|
86
90
|
).execute(next_primary(nil, session))
|
87
91
|
end
|
88
92
|
end
|
@@ -96,6 +100,7 @@ module Mongo
|
|
96
100
|
# @param [ Hash ] options The user options.
|
97
101
|
#
|
98
102
|
# @option options [ Session ] :session The session to use for the operation.
|
103
|
+
# @option options [ Hash ] :write_concern The write concern options.
|
99
104
|
#
|
100
105
|
# @return [ Result ] The response.
|
101
106
|
#
|
@@ -106,7 +111,8 @@ module Mongo
|
|
106
111
|
Operation::UpdateUser.new(
|
107
112
|
user: user,
|
108
113
|
db_name: database.name,
|
109
|
-
session: session
|
114
|
+
session: session,
|
115
|
+
write_concern: options[:write_concern] && WriteConcern.get(options[:write_concern]),
|
110
116
|
).execute(next_primary(nil, session))
|
111
117
|
end
|
112
118
|
end
|
@@ -121,7 +127,7 @@ module Mongo
|
|
121
127
|
#
|
122
128
|
# @option options [ Session ] :session The session to use for the operation.
|
123
129
|
#
|
124
|
-
# @return [
|
130
|
+
# @return [ Array ] An array wrapping a document containing information on a particular user.
|
125
131
|
#
|
126
132
|
# @since 2.1.0
|
127
133
|
def info(name, options = {})
|
data/lib/mongo/auth/x509.rb
CHANGED
@@ -17,7 +17,7 @@ require 'mongo/auth/x509/conversation'
|
|
17
17
|
module Mongo
|
18
18
|
module Auth
|
19
19
|
|
20
|
-
# Defines behavior for
|
20
|
+
# Defines behavior for X.509 authentication.
|
21
21
|
#
|
22
22
|
# @since 2.0.0
|
23
23
|
class X509
|
@@ -39,6 +39,16 @@ module Mongo
|
|
39
39
|
#
|
40
40
|
# @since 2.0.0
|
41
41
|
def initialize(user)
|
42
|
+
# The only valid database for X.509 authentication is $external.
|
43
|
+
if user.auth_source != '$external'
|
44
|
+
user_name_msg = if user.name
|
45
|
+
" #{user.name}"
|
46
|
+
else
|
47
|
+
''
|
48
|
+
end
|
49
|
+
raise Auth::InvalidConfiguration, "User#{user_name_msg} specifies auth source '#{user.auth_source}', but the only valid auth source for X.509 is '$external'"
|
50
|
+
end
|
51
|
+
|
42
52
|
@user = user
|
43
53
|
end
|
44
54
|
|
@@ -16,7 +16,7 @@ module Mongo
|
|
16
16
|
module Auth
|
17
17
|
class X509
|
18
18
|
|
19
|
-
# Defines behavior around a single
|
19
|
+
# Defines behavior around a single X.509 conversation between the
|
20
20
|
# client and server.
|
21
21
|
#
|
22
22
|
# @since 2.0.0
|
@@ -34,7 +34,7 @@ module Mongo
|
|
34
34
|
# @return [ User ] user The user for the conversation.
|
35
35
|
attr_reader :user
|
36
36
|
|
37
|
-
# Finalize the
|
37
|
+
# Finalize the X.509 conversation. This is meant to be iterated until
|
38
38
|
# the provided reply indicates the conversation is finished.
|
39
39
|
#
|
40
40
|
# @example Finalize the conversation.
|
@@ -50,7 +50,7 @@ module Mongo
|
|
50
50
|
validate!(reply)
|
51
51
|
end
|
52
52
|
|
53
|
-
# Start the
|
53
|
+
# Start the X.509 conversation. This returns the first message that
|
54
54
|
# needs to be sent to the server.
|
55
55
|
#
|
56
56
|
# @example Start the conversation.
|
@@ -58,7 +58,7 @@ module Mongo
|
|
58
58
|
#
|
59
59
|
# @param [ Mongo::Server::Connection ] connection The connection being authenticated.
|
60
60
|
#
|
61
|
-
# @return [ Protocol::Query ] The first
|
61
|
+
# @return [ Protocol::Query ] The first X.509 conversation message.
|
62
62
|
#
|
63
63
|
# @since 2.0.0
|
64
64
|
def start(connection = nil)
|
@@ -66,7 +66,16 @@ module Mongo
|
|
66
66
|
login[:user] = user.name if user.name
|
67
67
|
if connection && connection.features.op_msg_enabled?
|
68
68
|
selector = login
|
69
|
-
|
69
|
+
# The only valid database for X.509 authentication is $external.
|
70
|
+
if user.auth_source != '$external'
|
71
|
+
user_name_msg = if user.name
|
72
|
+
" #{user.name}"
|
73
|
+
else
|
74
|
+
''
|
75
|
+
end
|
76
|
+
raise Auth::InvalidConfiguration, "User#{user_name_msg} specifies auth source '#{user.auth_source}', but the only valid auth source for X.509 is '$external'"
|
77
|
+
end
|
78
|
+
selector[Protocol::Msg::DATABASE_IDENTIFIER] = '$external'
|
70
79
|
cluster_time = connection.mongos? && connection.cluster_time
|
71
80
|
selector[Operation::CLUSTER_TIME] = cluster_time if cluster_time
|
72
81
|
Protocol::Msg.new([], {}, selector)
|
@@ -96,7 +105,7 @@ module Mongo
|
|
96
105
|
|
97
106
|
def validate!(reply)
|
98
107
|
if reply.documents[0][Operation::Result::OK] != 1
|
99
|
-
raise Unauthorized.new(user, MECHANISM)
|
108
|
+
raise Unauthorized.new(user, used_mechanism: MECHANISM)
|
100
109
|
end
|
101
110
|
@reply = reply
|
102
111
|
end
|
@@ -30,6 +30,14 @@ module Mongo
|
|
30
30
|
#
|
31
31
|
# @api public for backwards compatibility only
|
32
32
|
def run!
|
33
|
+
if @stop_requested && @thread
|
34
|
+
wait_for_stop
|
35
|
+
if @thread.alive?
|
36
|
+
log_warn("Starting a new background thread in #{self}, but the previous background thread is still running")
|
37
|
+
@thread = nil
|
38
|
+
end
|
39
|
+
@stop_requested = false
|
40
|
+
end
|
33
41
|
if running?
|
34
42
|
@thread
|
35
43
|
else
|
@@ -81,6 +89,25 @@ module Mongo
|
|
81
89
|
# the middle of an operation.
|
82
90
|
@thread.kill
|
83
91
|
|
92
|
+
wait_for_stop
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def start!
|
98
|
+
@thread = Thread.new do
|
99
|
+
catch(:done) do
|
100
|
+
until @stop_requested
|
101
|
+
do_work
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Waits for the thread to die, with a timeout.
|
108
|
+
#
|
109
|
+
# Returns true if the thread died, false otherwise.
|
110
|
+
def wait_for_stop
|
84
111
|
# Wait for the thread to die. This is important in order to reliably
|
85
112
|
# clean up resources like connections knowing that no background
|
86
113
|
# thread will reconnect because it is still working.
|
@@ -106,23 +133,11 @@ module Mongo
|
|
106
133
|
false
|
107
134
|
else
|
108
135
|
@thread = nil
|
136
|
+
@stop_requested = false
|
109
137
|
true
|
110
138
|
end
|
111
139
|
end
|
112
140
|
|
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
141
|
# Override this method to do the work in the background thread.
|
127
142
|
def do_work
|
128
143
|
end
|
data/lib/mongo/client.rb
CHANGED
@@ -363,7 +363,8 @@ module Mongo
|
|
363
363
|
# @option options [ Hash ] :write Deprecated. Equivalent to :write_concern
|
364
364
|
# option.
|
365
365
|
# @option options [ Hash ] :write_concern The write concern options.
|
366
|
-
# Can be :w => Integer|String, :
|
366
|
+
# Can be :w => Integer|String, :wtimeout => Integer (in milliseconds),
|
367
|
+
# :j => Boolean, :fsync => Boolean.
|
367
368
|
# @option options [ Integer ] :zlib_compression_level The Zlib compression level to use, if using compression.
|
368
369
|
# See Ruby's Zlib module for valid levels.
|
369
370
|
# @option options [ Hash ] :resolv_options For internal driver use only.
|
@@ -371,11 +372,7 @@ module Mongo
|
|
371
372
|
#
|
372
373
|
# @since 2.0.0
|
373
374
|
def initialize(addresses_or_uri, options = nil)
|
374
|
-
|
375
|
-
options = options.dup
|
376
|
-
else
|
377
|
-
options = {}
|
378
|
-
end
|
375
|
+
options = options ? options.dup : {}
|
379
376
|
|
380
377
|
srv_uri = nil
|
381
378
|
if addresses_or_uri.is_a?(::String)
|
@@ -401,18 +398,12 @@ module Mongo
|
|
401
398
|
@srv_records = nil
|
402
399
|
end
|
403
400
|
|
404
|
-
unless options[:retry_reads] == false
|
405
|
-
options[:retry_reads] = true
|
406
|
-
end
|
407
|
-
unless options[:retry_writes] == false
|
408
|
-
options[:retry_writes] = true
|
409
|
-
end
|
410
|
-
|
411
401
|
# Special handling for sdam_proc as it is only used during client
|
412
402
|
# construction
|
413
403
|
sdam_proc = options.delete(:sdam_proc)
|
414
404
|
|
415
|
-
|
405
|
+
options = default_options(options).merge(options)
|
406
|
+
@options = validate_new_options!(options)
|
416
407
|
=begin WriteConcern object support
|
417
408
|
if @options[:write_concern].is_a?(WriteConcern::Base)
|
418
409
|
# Cache the instance so that we do not needlessly reconstruct it.
|
@@ -814,6 +805,23 @@ module Mongo
|
|
814
805
|
|
815
806
|
private
|
816
807
|
|
808
|
+
# Generate default client options based on the URI and options
|
809
|
+
# passed into the Client constructor.
|
810
|
+
def default_options(options)
|
811
|
+
Database::DEFAULT_OPTIONS.dup.tap do |default_options|
|
812
|
+
if options[:auth_mech] || options[:user]
|
813
|
+
default_options[:auth_source] = Auth::User.default_auth_source(options)
|
814
|
+
end
|
815
|
+
|
816
|
+
if options[:auth_mech] == :gssapi
|
817
|
+
default_options[:auth_mech_properties] = { service_name: 'mongodb' }
|
818
|
+
end
|
819
|
+
|
820
|
+
default_options[:retry_reads] = true
|
821
|
+
default_options[:retry_writes] = true
|
822
|
+
end
|
823
|
+
end
|
824
|
+
|
817
825
|
# If options[:session] is set, validates that session and returns it.
|
818
826
|
# If deployment supports sessions, creates a new session and returns it.
|
819
827
|
# The session is implicit unless options[:implicit] is given.
|
@@ -914,7 +922,7 @@ module Mongo
|
|
914
922
|
raise Mongo::Auth::InvalidConfiguration.new('password is not supported for mongodb_x509')
|
915
923
|
end
|
916
924
|
|
917
|
-
if ![
|
925
|
+
if !['$external', nil].include?(auth_source) && [:gssapi, :mongodb_x509].include?(auth_mech)
|
918
926
|
raise Mongo::Auth::InvalidConfiguration.new("#{auth_source} is an invalid auth source for #{auth_mech}; valid options are $external and nil")
|
919
927
|
end
|
920
928
|
|
@@ -296,7 +296,11 @@ module Mongo
|
|
296
296
|
end
|
297
297
|
|
298
298
|
def change_doc
|
299
|
-
{
|
299
|
+
{}.tap do |doc|
|
300
|
+
if @options[:full_document]
|
301
|
+
doc[:fullDocument] = @options[:full_document]
|
302
|
+
end
|
303
|
+
|
300
304
|
if resuming?
|
301
305
|
# We have a resume token once we retrieved any documents.
|
302
306
|
# However, if the first getMore fails and the user didn't pass
|
@@ -244,6 +244,9 @@ module Mongo
|
|
244
244
|
#
|
245
245
|
# @since 2.0.0
|
246
246
|
def distinct(field_name, opts = {})
|
247
|
+
if field_name.nil?
|
248
|
+
raise ArgumentError, 'Field name for distinct operation must be not nil'
|
249
|
+
end
|
247
250
|
cmd = { :distinct => collection.name,
|
248
251
|
:key => field_name.to_s,
|
249
252
|
:query => filter }
|
@@ -602,7 +605,7 @@ module Mongo
|
|
602
605
|
cmd.execute(server).cursor_ids.map do |cursor_id|
|
603
606
|
result = if server.features.find_command_enabled?
|
604
607
|
Operation::GetMore.new({
|
605
|
-
:selector => {:getMore => cursor_id,
|
608
|
+
:selector => {:getMore => BSON::Int64.new(cursor_id),
|
606
609
|
:collection => collection.name},
|
607
610
|
:db_name => database.name,
|
608
611
|
:session => session,
|
@@ -610,7 +613,7 @@ module Mongo
|
|
610
613
|
else
|
611
614
|
Operation::GetMore.new({
|
612
615
|
:to_return => 0,
|
613
|
-
:cursor_id => cursor_id,
|
616
|
+
:cursor_id => BSON::Int64.new(cursor_id),
|
614
617
|
:db_name => database.name,
|
615
618
|
:coll_name => collection.name
|
616
619
|
}).execute(server)
|