mongo 2.14.1 → 2.15.0.alpha
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/README.md +4 -1
- data/Rakefile +8 -15
- data/lib/mongo/auth/aws/conversation.rb +1 -4
- data/lib/mongo/auth/base.rb +13 -7
- data/lib/mongo/auth/conversation_base.rb +32 -0
- data/lib/mongo/auth/cr/conversation.rb +6 -29
- data/lib/mongo/auth/gssapi/conversation.rb +4 -15
- data/lib/mongo/auth/ldap/conversation.rb +3 -14
- data/lib/mongo/auth/sasl_conversation_base.rb +1 -13
- data/lib/mongo/auth/scram_conversation_base.rb +7 -34
- data/lib/mongo/auth/user/view.rb +16 -9
- data/lib/mongo/auth/x509/conversation.rb +4 -25
- data/lib/mongo/bulk_write.rb +21 -18
- data/lib/mongo/client.rb +82 -6
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +6 -2
- data/lib/mongo/cluster.rb +19 -2
- data/lib/mongo/collection/view/aggregation.rb +1 -1
- data/lib/mongo/collection/view/change_stream.rb +1 -1
- data/lib/mongo/collection/view/iterable.rb +7 -17
- data/lib/mongo/collection/view/map_reduce.rb +2 -2
- data/lib/mongo/collection/view/readable.rb +42 -20
- data/lib/mongo/collection/view/writable.rb +14 -14
- data/lib/mongo/collection.rb +6 -6
- data/lib/mongo/cursor.rb +2 -12
- data/lib/mongo/database/view.rb +1 -1
- data/lib/mongo/database.rb +8 -3
- data/lib/mongo/error/bulk_write_error.rb +17 -3
- data/lib/mongo/error/internal_driver_error.rb +22 -0
- data/lib/mongo/error/operation_failure.rb +21 -2
- data/lib/mongo/error/parser.rb +65 -12
- data/lib/mongo/error/server_api_conflict.rb +23 -0
- data/lib/mongo/error/server_api_not_supported.rb +24 -0
- data/lib/mongo/error/unmet_dependency.rb +21 -0
- data/lib/mongo/error.rb +9 -1
- data/lib/mongo/index/view.rb +21 -11
- data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +27 -16
- data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +26 -15
- data/lib/mongo/monitoring.rb +13 -4
- data/lib/mongo/operation/collections_info/command.rb +2 -2
- data/lib/mongo/operation/collections_info.rb +18 -1
- data/lib/mongo/operation/context.rb +99 -0
- data/lib/mongo/operation/indexes.rb +15 -1
- data/lib/mongo/operation/insert/command.rb +2 -2
- data/lib/mongo/operation/insert/legacy.rb +2 -2
- data/lib/mongo/operation/insert/op_msg.rb +2 -2
- data/lib/mongo/operation/list_collections/result.rb +4 -1
- data/lib/mongo/operation/parallel_scan/command.rb +2 -1
- data/lib/mongo/operation/result.rb +2 -0
- data/lib/mongo/operation/shared/executable.rb +24 -14
- data/lib/mongo/operation/shared/executable_no_validate.rb +2 -2
- data/lib/mongo/operation/shared/op_msg_or_command.rb +1 -7
- data/lib/mongo/operation/shared/op_msg_or_find_command.rb +1 -7
- data/lib/mongo/operation/shared/polymorphic_operation.rb +39 -0
- data/lib/mongo/operation/shared/read_preference_supported.rb +36 -38
- data/lib/mongo/operation/shared/response_handling.rb +23 -23
- data/lib/mongo/operation/shared/sessions_supported.rb +15 -5
- data/lib/mongo/operation/shared/write.rb +8 -18
- data/lib/mongo/operation.rb +2 -2
- data/lib/mongo/protocol/compressed.rb +51 -5
- data/lib/mongo/protocol/message.rb +20 -2
- data/lib/mongo/protocol/msg.rb +38 -13
- data/lib/mongo/protocol/query.rb +11 -11
- data/lib/mongo/query_cache.rb +30 -0
- data/lib/mongo/retryable.rb +1 -1
- data/lib/mongo/server/app_metadata.rb +52 -18
- data/lib/mongo/server/connection.rb +5 -0
- data/lib/mongo/server/connection_base.rb +13 -10
- data/lib/mongo/server/connection_pool.rb +6 -2
- data/lib/mongo/server/description/features.rb +9 -8
- data/lib/mongo/server/description.rb +4 -0
- data/lib/mongo/server/monitor/app_metadata.rb +1 -1
- data/lib/mongo/server/monitor/connection.rb +9 -10
- data/lib/mongo/server/monitor.rb +20 -1
- data/lib/mongo/server/pending_connection.rb +24 -6
- data/lib/mongo/server/push_monitor.rb +11 -1
- data/lib/mongo/server.rb +7 -1
- data/lib/mongo/server_selector/secondary_preferred.rb +7 -2
- data/lib/mongo/session/session_pool.rb +4 -2
- data/lib/mongo/session.rb +2 -2
- data/lib/mongo/socket/ssl.rb +8 -0
- data/lib/mongo/socket.rb +29 -4
- data/lib/mongo/uri/options_mapper.rb +38 -0
- data/lib/mongo/utils.rb +15 -0
- data/lib/mongo/version.rb +1 -1
- data/lib/mongo.rb +23 -0
- data/spec/README.md +24 -1
- data/spec/integration/auth_spec.rb +25 -15
- data/spec/integration/bulk_write_error_message_spec.rb +41 -0
- data/spec/integration/change_stream_spec.rb +4 -4
- data/spec/integration/command_monitoring_spec.rb +2 -2
- data/spec/integration/connection_spec.rb +2 -0
- data/spec/integration/docs_examples_spec.rb +8 -1
- data/spec/integration/fork_reconnect_spec.rb +4 -1
- data/spec/integration/ocsp_verifier_spec.rb +13 -7
- data/spec/integration/operation_failure_code_spec.rb +1 -1
- data/spec/integration/operation_failure_message_spec.rb +90 -0
- data/spec/integration/query_cache_spec.rb +0 -45
- data/spec/integration/reconnect_spec.rb +1 -1
- data/spec/integration/snappy_compression_spec.rb +25 -0
- data/spec/integration/srv_monitoring_spec.rb +1 -1
- data/spec/integration/transactions_examples_spec.rb +6 -0
- data/spec/integration/zlib_compression_spec.rb +1 -1
- data/spec/integration/zstd_compression_spec.rb +26 -0
- data/spec/lite_spec_helper.rb +7 -1
- data/spec/mongo/address_spec.rb +15 -11
- data/spec/mongo/auth/ldap/conversation_spec.rb +1 -1
- data/spec/mongo/auth/ldap_spec.rb +5 -1
- data/spec/mongo/auth/scram_negotiation_spec.rb +1 -1
- data/spec/mongo/auth/scram_spec.rb +1 -1
- data/spec/mongo/auth/x509/conversation_spec.rb +3 -3
- data/spec/mongo/client_construction_spec.rb +207 -33
- data/spec/mongo/client_spec.rb +17 -0
- data/spec/mongo/cluster_spec.rb +1 -0
- data/spec/mongo/collection/view/explainable_spec.rb +1 -1
- data/spec/mongo/collection/view/readable_spec.rb +33 -19
- data/spec/mongo/collection_crud_spec.rb +4357 -0
- data/spec/mongo/collection_ddl_spec.rb +534 -0
- data/spec/mongo/collection_spec.rb +5 -4859
- data/spec/mongo/database_spec.rb +66 -4
- data/spec/mongo/error/bulk_write_error_spec.rb +3 -3
- data/spec/mongo/error/parser_spec.rb +37 -6
- data/spec/mongo/index/view_spec.rb +4 -0
- data/spec/mongo/monitoring/event/server_heartbeat_failed_spec.rb +1 -1
- data/spec/mongo/monitoring/event/server_heartbeat_succeeded_spec.rb +1 -1
- data/spec/mongo/operation/aggregate_spec.rb +2 -1
- data/spec/mongo/operation/collections_info_spec.rb +4 -1
- data/spec/mongo/operation/command_spec.rb +6 -3
- data/spec/mongo/operation/create_index_spec.rb +6 -3
- data/spec/mongo/operation/create_user_spec.rb +6 -3
- data/spec/mongo/operation/delete/bulk_spec.rb +9 -6
- data/spec/mongo/operation/delete_spec.rb +11 -7
- data/spec/mongo/operation/drop_index_spec.rb +6 -2
- data/spec/mongo/operation/find/legacy_spec.rb +3 -1
- data/spec/mongo/operation/get_more_spec.rb +3 -1
- data/spec/mongo/operation/indexes_spec.rb +5 -1
- data/spec/mongo/operation/insert/bulk_spec.rb +10 -7
- data/spec/mongo/operation/insert_spec.rb +15 -12
- data/spec/mongo/operation/map_reduce_spec.rb +5 -2
- data/spec/mongo/operation/read_preference_legacy_spec.rb +19 -9
- data/spec/mongo/operation/read_preference_op_msg_spec.rb +3 -3
- data/spec/mongo/operation/remove_user_spec.rb +6 -3
- data/spec/mongo/operation/result_spec.rb +1 -1
- data/spec/mongo/operation/update/bulk_spec.rb +9 -6
- data/spec/mongo/operation/update_spec.rb +10 -7
- data/spec/mongo/operation/update_user_spec.rb +4 -1
- data/spec/mongo/protocol/compressed_spec.rb +26 -12
- data/spec/mongo/query_cache_middleware_spec.rb +55 -0
- data/spec/mongo/retryable_spec.rb +3 -2
- data/spec/mongo/server/app_metadata_shared.rb +7 -33
- data/spec/mongo/server/app_metadata_spec.rb +2 -0
- data/spec/mongo/server/connection_pool/populator_spec.rb +3 -1
- data/spec/mongo/server/connection_pool_spec.rb +1 -1
- data/spec/mongo/server/connection_spec.rb +24 -17
- data/spec/mongo/server/monitor/connection_spec.rb +17 -7
- data/spec/mongo/server/monitor_spec.rb +9 -1
- data/spec/mongo/server_selector/secondary_preferred_spec.rb +6 -6
- data/spec/mongo/server_spec.rb +15 -2
- data/spec/mongo/socket/ssl_spec.rb +40 -0
- data/spec/mongo/socket_spec.rb +2 -2
- data/spec/mongo/tls_context_hooks_spec.rb +37 -0
- data/spec/runners/connection_string.rb +0 -4
- data/spec/runners/crud/requirement.rb +40 -3
- data/spec/runners/crud/verifier.rb +8 -0
- data/spec/runners/transactions/operation.rb +1 -1
- data/spec/runners/transactions/test.rb +1 -0
- data/spec/runners/unified/assertions.rb +249 -0
- data/spec/runners/unified/change_stream_operations.rb +26 -0
- data/spec/runners/unified/crud_operations.rb +199 -0
- data/spec/runners/unified/ddl_operations.rb +96 -0
- data/spec/runners/unified/entity_map.rb +39 -0
- data/spec/runners/unified/error.rb +25 -0
- data/spec/runners/unified/event_subscriber.rb +91 -0
- data/spec/runners/unified/exceptions.rb +21 -0
- data/spec/runners/unified/grid_fs_operations.rb +55 -0
- data/spec/runners/unified/support_operations.rb +250 -0
- data/spec/runners/unified/test.rb +393 -0
- data/spec/runners/unified/test_group.rb +28 -0
- data/spec/runners/unified/using_hash.rb +31 -0
- data/spec/runners/unified.rb +96 -0
- data/spec/shared/lib/mrss/cluster_config.rb +0 -3
- data/spec/shared/lib/mrss/docker_runner.rb +0 -3
- data/spec/shared/lib/mrss/lite_constraints.rb +0 -16
- data/spec/shared/lib/mrss/server_version_registry.rb +0 -3
- data/spec/shared/lib/mrss/spec_organizer.rb +0 -3
- data/spec/shared/shlib/server.sh +1 -1
- data/spec/spec_helper.rb +4 -1
- data/spec/spec_tests/crud_unified_spec.rb +10 -0
- data/spec/spec_tests/data/change_streams/change-streams.yml +0 -1
- data/spec/spec_tests/data/crud_unified/estimatedDocumentCount.yml +267 -0
- data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount-4.9.yml +60 -0
- data/spec/spec_tests/data/retryable_reads/{estimatedDocumentCount.yml → estimatedDocumentCount-pre4.9.yml} +2 -0
- data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount-serverErrors-4.9.yml +146 -0
- data/spec/spec_tests/data/retryable_reads/{estimatedDocumentCount-serverErrors.yml → estimatedDocumentCount-serverErrors-pre4.9.yml} +2 -0
- data/spec/spec_tests/data/retryable_reads/listIndexNames.yml +1 -1
- data/spec/spec_tests/data/unified/valid-fail/operation-failure.yml +31 -0
- data/spec/spec_tests/data/unified/valid-pass/poc-change-streams.yml +220 -0
- data/spec/spec_tests/data/unified/valid-pass/poc-command-monitoring.yml +102 -0
- data/spec/spec_tests/data/unified/valid-pass/poc-crud.yml +184 -0
- data/spec/spec_tests/data/unified/valid-pass/poc-gridfs.yml +155 -0
- data/spec/spec_tests/data/unified/valid-pass/poc-retryable-reads.yml +193 -0
- data/spec/spec_tests/data/unified/valid-pass/poc-retryable-writes.yml +210 -0
- data/spec/spec_tests/data/unified/valid-pass/poc-sessions.yml +215 -0
- data/spec/spec_tests/data/unified/valid-pass/poc-transactions-convenient-api.yml +235 -0
- data/spec/spec_tests/data/unified/valid-pass/poc-transactions-mongos-pin-auto.yml +169 -0
- data/spec/spec_tests/data/unified/valid-pass/poc-transactions.yml +170 -0
- data/spec/spec_tests/data/uri_options/compression-options.yml +1 -1
- data/spec/spec_tests/data/versioned_api/crud-api-version-1-strict.yml +416 -0
- data/spec/spec_tests/data/versioned_api/crud-api-version-1.yml +409 -0
- data/spec/spec_tests/data/versioned_api/runcommand-helper-no-api-version-declared.yml +67 -0
- data/spec/spec_tests/data/versioned_api/test-commands-deprecation-errors.yml +47 -0
- data/spec/spec_tests/data/versioned_api/test-commands-strict-mode.yml +44 -0
- data/spec/spec_tests/data/versioned_api/transaction-handling.yml +180 -0
- data/spec/spec_tests/unified_spec.rb +15 -0
- data/spec/spec_tests/uri_options_spec.rb +16 -0
- data/spec/spec_tests/versioned_api_spec.rb +10 -0
- data/spec/support/client_registry.rb +4 -8
- data/spec/support/client_registry_macros.rb +4 -4
- data/spec/support/common_shortcuts.rb +15 -1
- data/spec/support/shared/session.rb +2 -2
- data/spec/support/spec_config.rb +42 -11
- data/spec/support/utils.rb +64 -3
- data.tar.gz.sig +0 -0
- metadata +1005 -915
- metadata.gz.sig +0 -0
- data/lib/mongo/operation/shared/collections_info_or_list_collections.rb +0 -58
- data/lib/mongo/operation/shared/op_msg_or_list_indexes_command.rb +0 -47
- data/spec/integration/secondary_reads_spec.rb +0 -102
- data/spec/support/cluster_config.rb +0 -207
data/lib/mongo/client.rb
CHANGED
@@ -85,6 +85,7 @@ module Mongo
|
|
85
85
|
:retry_writes,
|
86
86
|
:scan,
|
87
87
|
:sdam_proc,
|
88
|
+
:server_api,
|
88
89
|
:server_selection_timeout,
|
89
90
|
:socket_timeout,
|
90
91
|
:ssl,
|
@@ -114,7 +115,16 @@ module Mongo
|
|
114
115
|
# The compression algorithms supported by the driver.
|
115
116
|
#
|
116
117
|
# @since 2.5.0
|
117
|
-
VALID_COMPRESSORS = [
|
118
|
+
VALID_COMPRESSORS = [
|
119
|
+
Mongo::Protocol::Compressed::ZSTD,
|
120
|
+
Mongo::Protocol::Compressed::SNAPPY,
|
121
|
+
Mongo::Protocol::Compressed::ZLIB
|
122
|
+
].freeze
|
123
|
+
|
124
|
+
# The known server API versions.
|
125
|
+
VALID_SERVER_API_VERSIONS = %w(
|
126
|
+
1
|
127
|
+
).freeze
|
118
128
|
|
119
129
|
# @return [ Mongo::Cluster ] cluster The cluster of servers for the client.
|
120
130
|
attr_reader :cluster
|
@@ -223,7 +233,7 @@ module Mongo
|
|
223
233
|
# @option options [ Array<String> ] :compressors A list of potential
|
224
234
|
# compressors to use, in order of preference. The driver chooses the
|
225
235
|
# first compressor that is also supported by the server. Currently the
|
226
|
-
# driver only supports 'zlib'.
|
236
|
+
# driver only supports 'zstd, 'snappy' and 'zlib'.
|
227
237
|
# @option options [ true | false ] :direct_connection Whether to connect
|
228
238
|
# directly to the specified seed, bypassing topology discovery. Exactly
|
229
239
|
# one seed must be provided.
|
@@ -312,6 +322,11 @@ module Mongo
|
|
312
322
|
# in particular the cluster is nil at this time. sdam_proc should
|
313
323
|
# limit itself to calling #subscribe and #unsubscribe methods on the
|
314
324
|
# client only.
|
325
|
+
# @option options [ Hash ] :server_api The requested server API version.
|
326
|
+
# This hash can have the following items:
|
327
|
+
# - *:version* -- string
|
328
|
+
# - *:strict* -- boolean
|
329
|
+
# - *:deprecation_errors* -- boolean
|
315
330
|
# @option options [ Integer ] :server_selection_timeout The timeout in seconds
|
316
331
|
# for selecting a server for an operation.
|
317
332
|
# @option options [ Float ] :socket_timeout The timeout, in seconds, to
|
@@ -465,6 +480,18 @@ module Mongo
|
|
465
480
|
|
466
481
|
options = self.class.canonicalize_ruby_options(options)
|
467
482
|
|
483
|
+
# The server API version is specified to be a string.
|
484
|
+
# However, it is very annoying to always provide the number 1 as a string,
|
485
|
+
# therefore cast to the string type here.
|
486
|
+
if server_api = options[:server_api]
|
487
|
+
if server_api.is_a?(Hash)
|
488
|
+
server_api = Options::Redacted.new(server_api)
|
489
|
+
if (version = server_api[:version]).is_a?(Integer)
|
490
|
+
options[:server_api] = server_api.merge(version: version.to_s)
|
491
|
+
end
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
468
495
|
# Special handling for sdam_proc as it is only used during client
|
469
496
|
# construction
|
470
497
|
sdam_proc = options.delete(:sdam_proc)
|
@@ -499,7 +526,9 @@ module Mongo
|
|
499
526
|
validate_options!(addresses)
|
500
527
|
validate_authentication_options!
|
501
528
|
|
502
|
-
|
529
|
+
database_options = @options.dup
|
530
|
+
database_options.delete(:server_api)
|
531
|
+
@database = Database.new(self, @options[:database], database_options)
|
503
532
|
|
504
533
|
# Temporarily set monitoring so that event subscriptions can be
|
505
534
|
# set up without there being a cluster
|
@@ -697,9 +726,9 @@ module Mongo
|
|
697
726
|
# @return [ Mongo::Client ] A new client instance.
|
698
727
|
#
|
699
728
|
# @since 2.0.0
|
700
|
-
def with(new_options =
|
729
|
+
def with(new_options = nil)
|
701
730
|
clone.tap do |client|
|
702
|
-
opts = client.update_options(new_options)
|
731
|
+
opts = client.update_options(new_options || Options::Redacted.new)
|
703
732
|
Database.create(client)
|
704
733
|
# We can't use the same cluster if some options that would affect it
|
705
734
|
# have changed.
|
@@ -726,6 +755,8 @@ module Mongo
|
|
726
755
|
def update_options(new_options)
|
727
756
|
old_options = @options
|
728
757
|
|
758
|
+
new_options = self.class.canonicalize_ruby_options(new_options || {})
|
759
|
+
|
729
760
|
validate_new_options!(new_options).tap do |opts|
|
730
761
|
# Our options are frozen
|
731
762
|
options = @options.dup
|
@@ -1127,7 +1158,7 @@ module Mongo
|
|
1127
1158
|
# The argument may contain a subset of options that the client will
|
1128
1159
|
# eventually have; this method validates each of the provided options
|
1129
1160
|
# but does not check for interactions between combinations of options.
|
1130
|
-
def validate_new_options!(opts
|
1161
|
+
def validate_new_options!(opts)
|
1131
1162
|
return Options::Redacted.new unless opts
|
1132
1163
|
if opts[:read_concern]
|
1133
1164
|
# Raise an error for non user-settable options
|
@@ -1146,6 +1177,23 @@ module Mongo
|
|
1146
1177
|
end
|
1147
1178
|
end
|
1148
1179
|
|
1180
|
+
if server_api = opts[:server_api]
|
1181
|
+
unless server_api.is_a?(Hash)
|
1182
|
+
raise ArgumentError, ":server_api value must be a hash: #{server_api}"
|
1183
|
+
end
|
1184
|
+
|
1185
|
+
extra_keys = server_api.keys - %w(version strict deprecation_errors)
|
1186
|
+
unless extra_keys.empty?
|
1187
|
+
raise ArgumentError, "Unknown keys under :server_api: #{extra_keys.map(&:inspect).join(', ')}"
|
1188
|
+
end
|
1189
|
+
|
1190
|
+
if version = server_api[:version]
|
1191
|
+
unless VALID_SERVER_API_VERSIONS.include?(version)
|
1192
|
+
raise ArgumentError, "Unknown server API version: #{version}"
|
1193
|
+
end
|
1194
|
+
end
|
1195
|
+
end
|
1196
|
+
|
1149
1197
|
Lint.validate_underscore_read_preference(opts[:read])
|
1150
1198
|
Lint.validate_read_concern_option(opts[:read_concern])
|
1151
1199
|
opts.each.inject(Options::Redacted.new) do |_options, (k, v)|
|
@@ -1155,6 +1203,15 @@ module Mongo
|
|
1155
1203
|
validate_read!(key, opts)
|
1156
1204
|
if key == :compressors
|
1157
1205
|
compressors = valid_compressors(v)
|
1206
|
+
|
1207
|
+
if compressors.include?('snappy')
|
1208
|
+
validate_snappy_compression!
|
1209
|
+
end
|
1210
|
+
|
1211
|
+
if compressors.include?('zstd')
|
1212
|
+
validate_zstd_compression!
|
1213
|
+
end
|
1214
|
+
|
1158
1215
|
_options[key] = compressors unless compressors.empty?
|
1159
1216
|
else
|
1160
1217
|
_options[key] = v
|
@@ -1311,11 +1368,30 @@ module Mongo
|
|
1311
1368
|
"This compressor will not be used.")
|
1312
1369
|
false
|
1313
1370
|
else
|
1371
|
+
|
1314
1372
|
true
|
1315
1373
|
end
|
1316
1374
|
end
|
1317
1375
|
end
|
1318
1376
|
|
1377
|
+
def validate_snappy_compression!
|
1378
|
+
return if defined?(Snappy)
|
1379
|
+
require 'snappy'
|
1380
|
+
rescue LoadError => e
|
1381
|
+
raise Error::UnmetDependency, "Cannot enable snappy compression because the snappy gem " \
|
1382
|
+
"has not been installed. Add \"gem 'snappy'\" to your Gemfile and run " \
|
1383
|
+
"\"bundle install\" to install the gem. (#{e.class}: #{e})"
|
1384
|
+
end
|
1385
|
+
|
1386
|
+
def validate_zstd_compression!
|
1387
|
+
return if defined?(Zstd)
|
1388
|
+
require 'zstd-ruby'
|
1389
|
+
rescue LoadError => e
|
1390
|
+
raise Error::UnmetDependency, "Cannot enable zstd compression because the zstd-ruby gem " \
|
1391
|
+
"has not been installed. Add \"gem 'zstd-ruby'\" to your Gemfile and run " \
|
1392
|
+
"\"bundle install\" to install the gem. (#{e.class}: #{e})"
|
1393
|
+
end
|
1394
|
+
|
1319
1395
|
def validate_max_min_pool_size!(option, opts)
|
1320
1396
|
if option == :min_pool_size && opts[:min_pool_size]
|
1321
1397
|
max = opts[:max_pool_size] || Server::ConnectionPool::DEFAULT_MAX_SIZE
|
@@ -130,16 +130,20 @@ module Mongo
|
|
130
130
|
end
|
131
131
|
|
132
132
|
to_kill_copy.each do |server, op_specs|
|
133
|
+
options = {
|
134
|
+
server_api: server.options[:server_api],
|
135
|
+
}
|
136
|
+
context = Operation::Context.new(options: options)
|
133
137
|
op_specs.each do |op_spec|
|
134
138
|
if server.features.find_command_enabled?
|
135
139
|
Cursor::Builder::KillCursorsCommand.update_cursors(op_spec, active_cursors_copy.to_a)
|
136
140
|
if Cursor::Builder::KillCursorsCommand.get_cursors_list(op_spec).size > 0
|
137
|
-
Operation::KillCursors.new(op_spec).execute(server,
|
141
|
+
Operation::KillCursors.new(op_spec).execute(server, context: context)
|
138
142
|
end
|
139
143
|
else
|
140
144
|
Cursor::Builder::OpKillCursors.update_cursors(op_spec, active_cursors_copy.to_a)
|
141
145
|
if Cursor::Builder::OpKillCursors.get_cursors_list(op_spec).size > 0
|
142
|
-
Operation::KillCursors.new(op_spec).execute(server,
|
146
|
+
Operation::KillCursors.new(op_spec).execute(server, context: context)
|
143
147
|
end
|
144
148
|
end
|
145
149
|
end
|
data/lib/mongo/cluster.rb
CHANGED
@@ -107,6 +107,11 @@ module Mongo
|
|
107
107
|
# for the server monitor to refresh its description via ismaster.
|
108
108
|
# @option options [ Hash ] :resolv_options For internal driver use only.
|
109
109
|
# Options to pass through to Resolv::DNS constructor for SRV lookups.
|
110
|
+
# @option options [ Hash ] :server_api The requested server API version.
|
111
|
+
# This hash can have the following items:
|
112
|
+
# - *:version* -- string
|
113
|
+
# - *:strict* -- boolean
|
114
|
+
# - *:deprecation_errors* -- boolean
|
110
115
|
#
|
111
116
|
# @since 2.0.0
|
112
117
|
def initialize(seeds, monitoring, options = Options::Redacted.new)
|
@@ -129,7 +134,9 @@ module Mongo
|
|
129
134
|
@servers = []
|
130
135
|
@monitoring = monitoring
|
131
136
|
@event_listeners = Event::Listeners.new
|
132
|
-
@app_metadata = Server::AppMetadata.new(@options)
|
137
|
+
@app_metadata = Server::AppMetadata.new(@options.merge(purpose: :application))
|
138
|
+
@monitor_app_metadata = Server::Monitor::AppMetadata.new(@options.merge(purpose: :monitor))
|
139
|
+
@push_monitor_app_metadata = Server::Monitor::AppMetadata.new(@options.merge(purpose: :push_monitor))
|
133
140
|
@cluster_time_lock = Mutex.new
|
134
141
|
@cluster_time = nil
|
135
142
|
@srv_monitor_lock = Mutex.new
|
@@ -241,7 +248,11 @@ module Mongo
|
|
241
248
|
# the servers list above and the wait call below, we should not
|
242
249
|
# wait for the full remaining time - wait for up to 1 second, then
|
243
250
|
# recheck the state.
|
244
|
-
|
251
|
+
begin
|
252
|
+
server_selection_semaphore.wait([time_remaining, 1].min)
|
253
|
+
rescue ::Timeout::Error
|
254
|
+
# nothing
|
255
|
+
end
|
245
256
|
end
|
246
257
|
end
|
247
258
|
|
@@ -285,6 +296,12 @@ module Mongo
|
|
285
296
|
# @since 2.4.0
|
286
297
|
attr_reader :app_metadata
|
287
298
|
|
299
|
+
# @api private
|
300
|
+
attr_reader :monitor_app_metadata
|
301
|
+
|
302
|
+
# @api private
|
303
|
+
attr_reader :push_monitor_app_metadata
|
304
|
+
|
288
305
|
# @return [ Array<String> ] The addresses of seed servers. Contains
|
289
306
|
# addresses that were given to Cluster when it was instantiated, not
|
290
307
|
# current addresses that the cluster is using as a result of SDAM.
|
@@ -134,7 +134,7 @@ module Mongo
|
|
134
134
|
server = cluster.next_primary(nil, session)
|
135
135
|
end
|
136
136
|
validate_collation!(server)
|
137
|
-
initial_query_op(session).execute(server, client: client)
|
137
|
+
initial_query_op(session).execute(server, context: Operation::Context.new(client: client, session: session))
|
138
138
|
end
|
139
139
|
|
140
140
|
def validate_collation!(server)
|
@@ -346,7 +346,7 @@ module Mongo
|
|
346
346
|
end
|
347
347
|
|
348
348
|
def send_initial_query(server, session)
|
349
|
-
initial_query_op(session).execute(server, client: client)
|
349
|
+
initial_query_op(session).execute(server, context: Operation::Context.new(client: client, session: session))
|
350
350
|
end
|
351
351
|
|
352
352
|
def time_to_bson_timestamp(time)
|
@@ -35,28 +35,18 @@ module Mongo
|
|
35
35
|
#
|
36
36
|
# @yieldparam [ Hash ] Each matching document.
|
37
37
|
def each
|
38
|
-
|
39
|
-
# the documents we have in it are not the complete result set and
|
40
|
-
# we have no way of completing that iteration.
|
41
|
-
# Therefore, discard that cursor and start iteration again.
|
42
|
-
# The case of the caching cursor not being closed and not having
|
43
|
-
# been fully iterated isn't tested - see RUBY-2773.
|
44
|
-
@cursor = if use_query_cache? && cached_cursor && (
|
45
|
-
cached_cursor.fully_iterated? || !cached_cursor.closed?
|
46
|
-
)
|
38
|
+
@cursor = if use_query_cache? && cached_cursor
|
47
39
|
cached_cursor
|
48
40
|
else
|
49
41
|
session = client.send(:get_session, @options)
|
50
|
-
select_cursor(session)
|
51
|
-
if use_query_cache?
|
52
|
-
# No need to store the cursor in the query cache if there is
|
53
|
-
# already a cached cursor stored at this key.
|
54
|
-
QueryCache.set(cursor, **cache_options)
|
55
|
-
end
|
56
|
-
end
|
42
|
+
select_cursor(session)
|
57
43
|
end
|
58
44
|
|
59
45
|
if use_query_cache?
|
46
|
+
# No need to store the cursor in the query cache if there is
|
47
|
+
# already a cached cursor stored at this key.
|
48
|
+
QueryCache.set(@cursor, **cache_options) unless cached_cursor
|
49
|
+
|
60
50
|
# If a query with a limit is performed, the query cache will
|
61
51
|
# re-use results from an earlier query with the same or larger
|
62
52
|
# limit, and then impose the lower limit during iteration.
|
@@ -167,7 +157,7 @@ module Mongo
|
|
167
157
|
|
168
158
|
def send_initial_query(server, session = nil)
|
169
159
|
validate_collation!(server, collation)
|
170
|
-
initial_query_op(server, session).execute(server, client: client)
|
160
|
+
initial_query_op(server, session).execute(server, context: Operation::Context.new(client: client, session: session))
|
171
161
|
end
|
172
162
|
|
173
163
|
def use_query_cache?
|
@@ -242,7 +242,7 @@ module Mongo
|
|
242
242
|
server = cluster.next_primary(nil, session)
|
243
243
|
end
|
244
244
|
validate_collation!(server)
|
245
|
-
initial_query_op(session).execute(server, client: client)
|
245
|
+
initial_query_op(session).execute(server, context: Operation::Context.new(client: client, session: session))
|
246
246
|
end
|
247
247
|
|
248
248
|
def fetch_query_spec
|
@@ -262,7 +262,7 @@ module Mongo
|
|
262
262
|
end
|
263
263
|
|
264
264
|
def send_fetch_query(server, session)
|
265
|
-
fetch_query_op(server, session).execute(server, client: client)
|
265
|
+
fetch_query_op(server, session).execute(server, context: Operation::Context.new(client: client, session: session))
|
266
266
|
end
|
267
267
|
|
268
268
|
def validate_collation!(server)
|
@@ -172,8 +172,8 @@ module Mongo
|
|
172
172
|
:db_name => database.name,
|
173
173
|
:options => {:limit => -1},
|
174
174
|
:read => read_pref,
|
175
|
-
:session => session
|
176
|
-
).execute(server, client: client)
|
175
|
+
:session => session,
|
176
|
+
).execute(server, context: Operation::Context.new(client: client, session: session))
|
177
177
|
end.n.to_i
|
178
178
|
end
|
179
179
|
end
|
@@ -230,24 +230,46 @@ module Mongo
|
|
230
230
|
raise ArgumentError, "Cannot call estimated_document_count when querying with a filter"
|
231
231
|
end
|
232
232
|
|
233
|
-
cmd = { count: collection.name }
|
234
|
-
cmd[:maxTimeMS] = opts[:max_time_ms] if opts[:max_time_ms]
|
235
|
-
if read_concern
|
236
|
-
cmd[:readConcern] = Options::Mapper.transform_values_to_strings(
|
237
|
-
read_concern)
|
238
|
-
end
|
239
233
|
Mongo::Lint.validate_underscore_read_preference(opts[:read])
|
240
234
|
read_pref = opts[:read] || read_preference
|
241
235
|
selector = ServerSelector.get(read_pref || server_selector)
|
242
236
|
with_session(opts) do |session|
|
237
|
+
context = Operation::Context.new(client: client, session: session)
|
243
238
|
read_with_retry(session, selector) do |server|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
239
|
+
if server.description.server_version_gte?('5.0')
|
240
|
+
pipeline = [
|
241
|
+
{'$collStats' => {'count' => {}}},
|
242
|
+
{'$group' => {'_id' => 1, 'n' => {'$sum' => '$count'}}},
|
243
|
+
]
|
244
|
+
spec = Builder::Aggregation.new(pipeline, self, options.merge(session: session)).specification
|
245
|
+
result = Operation::Aggregate.new(spec).execute(server, context: context)
|
246
|
+
result.documents.first.fetch('n')
|
247
|
+
else
|
248
|
+
cmd = { count: collection.name }
|
249
|
+
cmd[:maxTimeMS] = opts[:max_time_ms] if opts[:max_time_ms]
|
250
|
+
if read_concern
|
251
|
+
cmd[:readConcern] = Options::Mapper.transform_values_to_strings(
|
252
|
+
read_concern)
|
253
|
+
end
|
254
|
+
result = Operation::Count.new(
|
255
|
+
selector: cmd,
|
256
|
+
db_name: database.name,
|
257
|
+
read: read_pref,
|
258
|
+
session: session,
|
259
|
+
).execute(server, context: context)
|
260
|
+
result.n.to_i
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
rescue Error::OperationFailure => exc
|
265
|
+
if exc.code == 26
|
266
|
+
# NamespaceNotFound
|
267
|
+
# This should only happen with the aggregation pipeline path
|
268
|
+
# (server 4.9+). Previous servers should return 0 for nonexistent
|
269
|
+
# collections.
|
270
|
+
0
|
271
|
+
else
|
272
|
+
raise
|
251
273
|
end
|
252
274
|
end
|
253
275
|
|
@@ -290,8 +312,8 @@ module Mongo
|
|
290
312
|
:db_name => database.name,
|
291
313
|
:options => {:limit => -1},
|
292
314
|
:read => read_pref,
|
293
|
-
:session => session
|
294
|
-
}).execute(server, client: client)
|
315
|
+
:session => session,
|
316
|
+
}).execute(server, context: Operation::Context.new(client: client, session: session))
|
295
317
|
end.first['values']
|
296
318
|
end
|
297
319
|
end
|
@@ -626,21 +648,21 @@ module Mongo
|
|
626
648
|
:read_concern => read_concern,
|
627
649
|
:session => session,
|
628
650
|
}.merge!(options))
|
629
|
-
cmd.execute(server, client: client).cursor_ids.map do |cursor_id|
|
651
|
+
cmd.execute(server, context: Operation::Context.new(client: client, session: session)).cursor_ids.map do |cursor_id|
|
630
652
|
result = if server.with_connection { |connection| connection.features }.find_command_enabled?
|
631
653
|
Operation::GetMore.new({
|
632
654
|
:selector => {:getMore => BSON::Int64.new(cursor_id),
|
633
655
|
:collection => collection.name},
|
634
656
|
:db_name => database.name,
|
635
657
|
:session => session,
|
636
|
-
}).execute(server, client: client)
|
658
|
+
}).execute(server, context: Operation::Context.new(client: client, session: session))
|
637
659
|
else
|
638
660
|
Operation::GetMore.new({
|
639
661
|
:to_return => 0,
|
640
662
|
:cursor_id => BSON::Int64.new(cursor_id),
|
641
663
|
:db_name => database.name,
|
642
664
|
:coll_name => collection.name
|
643
|
-
}).execute(server, client: client)
|
665
|
+
}).execute(server, context: Operation::Context.new(client: client, session: session))
|
644
666
|
end
|
645
667
|
Cursor.new(self, result, server, session: session)
|
646
668
|
end
|
@@ -69,8 +69,8 @@ module Mongo
|
|
69
69
|
:selector => cmd,
|
70
70
|
:db_name => database.name,
|
71
71
|
:session => session,
|
72
|
-
:txn_num => txn_num
|
73
|
-
).execute(server, client: client)
|
72
|
+
:txn_num => txn_num,
|
73
|
+
).execute(server, context: Operation::Context.new(client: client, session: session))
|
74
74
|
end
|
75
75
|
end.first['value']
|
76
76
|
end
|
@@ -154,8 +154,8 @@ module Mongo
|
|
154
154
|
:selector => cmd,
|
155
155
|
:db_name => database.name,
|
156
156
|
:session => session,
|
157
|
-
:txn_num => txn_num
|
158
|
-
).execute(server, client: client)
|
157
|
+
:txn_num => txn_num,
|
158
|
+
).execute(server, context: Operation::Context.new(client: client, session: session))
|
159
159
|
end
|
160
160
|
end.first['value']
|
161
161
|
value unless value.nil? || value.empty?
|
@@ -198,8 +198,8 @@ module Mongo
|
|
198
198
|
:coll_name => collection.name,
|
199
199
|
:write_concern => write_concern,
|
200
200
|
:bypass_document_validation => !!opts[:bypass_document_validation],
|
201
|
-
:session => session
|
202
|
-
).execute(server, client: client)
|
201
|
+
:session => session,
|
202
|
+
).execute(server, context: Operation::Context.new(client: client, session: session))
|
203
203
|
end
|
204
204
|
end
|
205
205
|
end
|
@@ -242,8 +242,8 @@ module Mongo
|
|
242
242
|
:write_concern => write_concern,
|
243
243
|
:bypass_document_validation => !!opts[:bypass_document_validation],
|
244
244
|
:session => session,
|
245
|
-
:txn_num => txn_num
|
246
|
-
).execute(server, client: client)
|
245
|
+
:txn_num => txn_num,
|
246
|
+
).execute(server, context: Operation::Context.new(client: client, session: session))
|
247
247
|
end
|
248
248
|
end
|
249
249
|
end
|
@@ -298,8 +298,8 @@ module Mongo
|
|
298
298
|
:write_concern => write_concern,
|
299
299
|
:bypass_document_validation => !!opts[:bypass_document_validation],
|
300
300
|
:session => session,
|
301
|
-
:txn_num => txn_num
|
302
|
-
).execute(server, client: client)
|
301
|
+
:txn_num => txn_num,
|
302
|
+
).execute(server, context: Operation::Context.new(client: client, session: session))
|
303
303
|
end
|
304
304
|
end
|
305
305
|
end
|
@@ -355,8 +355,8 @@ module Mongo
|
|
355
355
|
:coll_name => collection.name,
|
356
356
|
:write_concern => write_concern,
|
357
357
|
:bypass_document_validation => !!opts[:bypass_document_validation],
|
358
|
-
:session => session
|
359
|
-
).execute(server, client: client)
|
358
|
+
:session => session,
|
359
|
+
).execute(server, context: Operation::Context.new(client: client, session: session))
|
360
360
|
end
|
361
361
|
end
|
362
362
|
end
|
@@ -412,8 +412,8 @@ module Mongo
|
|
412
412
|
:write_concern => write_concern,
|
413
413
|
:bypass_document_validation => !!opts[:bypass_document_validation],
|
414
414
|
:session => session,
|
415
|
-
:txn_num => txn_num
|
416
|
-
).execute(server, client: client)
|
415
|
+
:txn_num => txn_num,
|
416
|
+
).execute(server, context: Operation::Context.new(client: client, session: session))
|
417
417
|
end
|
418
418
|
end
|
419
419
|
end
|
data/lib/mongo/collection.rb
CHANGED
@@ -254,8 +254,8 @@ module Mongo
|
|
254
254
|
selector: operation,
|
255
255
|
db_name: database.name,
|
256
256
|
write_concern: write_concern,
|
257
|
-
session: session
|
258
|
-
}).execute(server, client: client)
|
257
|
+
session: session,
|
258
|
+
}).execute(server, context: Operation::Context.new(client: client, session: session))
|
259
259
|
end
|
260
260
|
end
|
261
261
|
|
@@ -287,8 +287,8 @@ module Mongo
|
|
287
287
|
selector: { :drop => name },
|
288
288
|
db_name: database.name,
|
289
289
|
write_concern: write_concern,
|
290
|
-
session: session
|
291
|
-
}).execute(next_primary(nil, session), client: client)
|
290
|
+
session: session,
|
291
|
+
}).execute(next_primary(nil, session), context: Operation::Context.new(client: client, session: session))
|
292
292
|
end
|
293
293
|
rescue Error::OperationFailure => ex
|
294
294
|
# NamespaceNotFound
|
@@ -579,8 +579,8 @@ module Mongo
|
|
579
579
|
:options => opts,
|
580
580
|
:id_generator => client.options[:id_generator],
|
581
581
|
:session => session,
|
582
|
-
:txn_num => txn_num
|
583
|
-
).execute(server, client: client)
|
582
|
+
:txn_num => txn_num,
|
583
|
+
).execute(server, context: Operation::Context.new(client: client, session: session))
|
584
584
|
end
|
585
585
|
end
|
586
586
|
end
|
data/lib/mongo/cursor.rb
CHANGED
@@ -209,12 +209,10 @@ module Mongo
|
|
209
209
|
unless closed?
|
210
210
|
if exhausted?
|
211
211
|
close
|
212
|
-
@fully_iterated = true
|
213
212
|
raise StopIteration
|
214
213
|
end
|
215
214
|
@documents = get_more
|
216
215
|
else
|
217
|
-
@fully_iterated = true
|
218
216
|
raise StopIteration
|
219
217
|
end
|
220
218
|
else
|
@@ -231,9 +229,6 @@ module Mongo
|
|
231
229
|
# over the last document, or if the batch is empty
|
232
230
|
if @documents.size <= 1
|
233
231
|
cache_batch_resume_token
|
234
|
-
if closed?
|
235
|
-
@fully_iterated = true
|
236
|
-
end
|
237
232
|
end
|
238
233
|
|
239
234
|
return @documents.shift
|
@@ -275,7 +270,7 @@ module Mongo
|
|
275
270
|
|
276
271
|
unregister
|
277
272
|
read_with_one_retry do
|
278
|
-
kill_cursors_operation.execute(@server, client: client)
|
273
|
+
kill_cursors_operation.execute(@server, context: Operation::Context.new(client: client, session: @session))
|
279
274
|
end
|
280
275
|
|
281
276
|
nil
|
@@ -350,12 +345,7 @@ module Mongo
|
|
350
345
|
# doing so may result in silent data loss, the driver no longer retries
|
351
346
|
# getMore operations in any circumstance.
|
352
347
|
# https://github.com/mongodb/specifications/blob/master/source/retryable-reads/retryable-reads.rst#qa
|
353
|
-
process(get_more_operation.execute(@server, client: client))
|
354
|
-
end
|
355
|
-
|
356
|
-
# @api private
|
357
|
-
def fully_iterated?
|
358
|
-
!!@fully_iterated
|
348
|
+
process(get_more_operation.execute(@server, context: Operation::Context.new(client: client, session: @session)))
|
359
349
|
end
|
360
350
|
|
361
351
|
private
|
data/lib/mongo/database/view.rb
CHANGED
@@ -189,7 +189,7 @@ module Mongo
|
|
189
189
|
end
|
190
190
|
|
191
191
|
def send_initial_query(server, session, options = {})
|
192
|
-
initial_query_op(session, options).execute(server, client: client)
|
192
|
+
initial_query_op(session, options).execute(server, context: Operation::Context.new(client: client, session: session))
|
193
193
|
end
|
194
194
|
end
|
195
195
|
end
|
data/lib/mongo/database.rb
CHANGED
@@ -104,6 +104,9 @@ module Mongo
|
|
104
104
|
#
|
105
105
|
# @since 2.0.0
|
106
106
|
def [](collection_name, options = {})
|
107
|
+
if options[:server_api]
|
108
|
+
raise ArgumentError, 'The :server_api option cannot be specified for collection objects. It can only be specified on Client level'
|
109
|
+
end
|
107
110
|
Collection.new(self, collection_name, options)
|
108
111
|
end
|
109
112
|
alias_method :collection, :[]
|
@@ -219,7 +222,9 @@ module Mongo
|
|
219
222
|
:session => session
|
220
223
|
)
|
221
224
|
|
222
|
-
op.execute(server,
|
225
|
+
op.execute(server,
|
226
|
+
context: Operation::Context.new(client: client, session: session),
|
227
|
+
options: execution_opts)
|
223
228
|
end
|
224
229
|
end
|
225
230
|
|
@@ -250,7 +255,7 @@ module Mongo
|
|
250
255
|
:db_name => name,
|
251
256
|
:read => preference,
|
252
257
|
:session => session
|
253
|
-
}).execute(server, client: client)
|
258
|
+
}).execute(server, context: Operation::Context.new(client: client, session: session))
|
254
259
|
end
|
255
260
|
end
|
256
261
|
end
|
@@ -281,7 +286,7 @@ module Mongo
|
|
281
286
|
db_name: name,
|
282
287
|
write_concern: write_concern,
|
283
288
|
session: session
|
284
|
-
}).execute(next_primary(nil, session), client: client)
|
289
|
+
}).execute(next_primary(nil, session), context: Operation::Context.new(client: client, session: session))
|
285
290
|
end
|
286
291
|
end
|
287
292
|
|