mongo 2.20.1 → 2.21.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -0
- data/Rakefile +2 -2
- data/lib/mongo/address.rb +22 -3
- data/lib/mongo/auth/aws/credentials_retriever.rb +70 -17
- data/lib/mongo/auth/base.rb +1 -1
- data/lib/mongo/bulk_write.rb +35 -2
- data/lib/mongo/client.rb +38 -6
- data/lib/mongo/client_encryption.rb +6 -3
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +6 -1
- data/lib/mongo/cluster/sdam_flow.rb +20 -7
- data/lib/mongo/cluster.rb +14 -4
- data/lib/mongo/collection/helpers.rb +1 -1
- data/lib/mongo/collection/view/aggregation/behavior.rb +131 -0
- data/lib/mongo/collection/view/aggregation.rb +33 -99
- data/lib/mongo/collection/view/builder/aggregation.rb +1 -7
- data/lib/mongo/collection/view/change_stream.rb +80 -27
- data/lib/mongo/collection/view/iterable.rb +76 -60
- data/lib/mongo/collection/view/map_reduce.rb +25 -8
- data/lib/mongo/collection/view/readable.rb +79 -30
- data/lib/mongo/collection/view/writable.rb +109 -48
- data/lib/mongo/collection/view.rb +43 -3
- data/lib/mongo/collection.rb +158 -23
- data/lib/mongo/crypt/auto_encrypter.rb +4 -6
- data/lib/mongo/crypt/binding.rb +4 -4
- data/lib/mongo/crypt/context.rb +20 -14
- data/lib/mongo/crypt/encryption_io.rb +56 -26
- data/lib/mongo/crypt/explicit_encrypter.rb +49 -20
- data/lib/mongo/crypt/explicit_encryption_context.rb +17 -11
- data/lib/mongo/crypt/kms/azure/credentials_retriever.rb +22 -6
- data/lib/mongo/crypt/kms/gcp/credentials_retriever.rb +29 -4
- data/lib/mongo/csot_timeout_holder.rb +119 -0
- data/lib/mongo/cursor/kill_spec.rb +5 -2
- data/lib/mongo/cursor/nontailable.rb +27 -0
- data/lib/mongo/cursor.rb +86 -24
- data/lib/mongo/cursor_host.rb +82 -0
- data/lib/mongo/database/view.rb +81 -14
- data/lib/mongo/database.rb +88 -18
- data/lib/mongo/error/operation_failure.rb +209 -204
- data/lib/mongo/error/server_timeout_error.rb +12 -0
- data/lib/mongo/error/socket_timeout_error.rb +3 -1
- data/lib/mongo/error/timeout_error.rb +23 -0
- data/lib/mongo/error.rb +2 -0
- data/lib/mongo/grid/fs_bucket.rb +45 -12
- data/lib/mongo/grid/stream/read.rb +15 -1
- data/lib/mongo/grid/stream/write.rb +21 -4
- data/lib/mongo/index/view.rb +77 -16
- data/lib/mongo/operation/context.rb +40 -2
- data/lib/mongo/operation/create_search_indexes/op_msg.rb +2 -2
- data/lib/mongo/operation/delete/op_msg.rb +2 -1
- data/lib/mongo/operation/drop_search_index/op_msg.rb +2 -2
- data/lib/mongo/operation/find/op_msg.rb +45 -0
- data/lib/mongo/operation/get_more/op_msg.rb +33 -0
- data/lib/mongo/operation/insert/op_msg.rb +3 -2
- data/lib/mongo/operation/insert/result.rb +4 -2
- data/lib/mongo/operation/list_collections/result.rb +1 -1
- data/lib/mongo/operation/map_reduce/result.rb +1 -1
- data/lib/mongo/operation/op_msg_base.rb +3 -1
- data/lib/mongo/operation/result.rb +26 -5
- data/lib/mongo/operation/shared/executable.rb +12 -1
- data/lib/mongo/operation/shared/op_msg_executable.rb +4 -1
- data/lib/mongo/operation/shared/response_handling.rb +3 -3
- data/lib/mongo/operation/shared/sessions_supported.rb +1 -1
- data/lib/mongo/operation/shared/timed.rb +52 -0
- data/lib/mongo/operation/shared/write.rb +4 -1
- data/lib/mongo/operation/update/op_msg.rb +2 -1
- data/lib/mongo/operation/update_search_index/op_msg.rb +2 -2
- data/lib/mongo/operation.rb +1 -0
- data/lib/mongo/protocol/message.rb +1 -4
- data/lib/mongo/protocol/msg.rb +2 -2
- data/lib/mongo/retryable/read_worker.rb +69 -29
- data/lib/mongo/retryable/write_worker.rb +49 -18
- data/lib/mongo/retryable.rb +8 -2
- data/lib/mongo/server/connection.rb +11 -5
- data/lib/mongo/server/connection_base.rb +22 -2
- data/lib/mongo/server/connection_pool.rb +32 -14
- data/lib/mongo/server/description/features.rb +1 -1
- data/lib/mongo/server/description.rb +18 -5
- data/lib/mongo/server/monitor.rb +7 -4
- data/lib/mongo/server/pending_connection.rb +7 -3
- data/lib/mongo/server/{round_trip_time_averager.rb → round_trip_time_calculator.rb} +25 -7
- data/lib/mongo/server.rb +11 -6
- data/lib/mongo/server_selector/base.rb +25 -9
- data/lib/mongo/session.rb +78 -9
- data/lib/mongo/socket/ssl.rb +109 -17
- data/lib/mongo/socket/tcp.rb +40 -6
- data/lib/mongo/socket.rb +154 -25
- data/lib/mongo/uri/options_mapper.rb +1 -0
- data/lib/mongo/version.rb +1 -1
- data/lib/mongo.rb +1 -0
- data/spec/atlas/atlas_connectivity_spec.rb +4 -0
- data/spec/atlas/operations_spec.rb +4 -0
- data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +2 -1
- data/spec/integration/client_side_encryption/auto_encryption_spec.rb +494 -487
- data/spec/integration/client_side_encryption/on_demand_aws_credentials_spec.rb +1 -1
- data/spec/integration/client_side_encryption/range_explicit_encryption_prose_spec.rb +66 -22
- data/spec/integration/client_side_operations_timeout/encryption_prose_spec.rb +131 -0
- data/spec/integration/connection_pool_populator_spec.rb +2 -0
- data/spec/integration/cursor_pinning_spec.rb +15 -60
- data/spec/integration/cursor_reaping_spec.rb +1 -1
- data/spec/integration/docs_examples_spec.rb +1 -1
- data/spec/integration/operation_failure_code_spec.rb +1 -1
- data/spec/integration/operation_failure_message_spec.rb +3 -3
- data/spec/integration/retryable_errors_spec.rb +2 -2
- data/spec/integration/sdam_error_handling_spec.rb +2 -1
- data/spec/integration/search_indexes_prose_spec.rb +4 -0
- data/spec/integration/server_spec.rb +4 -3
- data/spec/integration/transactions_api_examples_spec.rb +2 -0
- data/spec/kerberos/kerberos_spec.rb +4 -0
- data/spec/lite_spec_helper.rb +3 -1
- data/spec/mongo/auth/user/view_spec.rb +1 -1
- data/spec/mongo/caching_cursor_spec.rb +1 -1
- data/spec/mongo/client_encryption_spec.rb +1 -0
- data/spec/mongo/client_spec.rb +158 -4
- data/spec/mongo/collection/view/aggregation_spec.rb +14 -39
- data/spec/mongo/collection/view/change_stream_spec.rb +3 -3
- data/spec/mongo/collection_spec.rb +5 -6
- data/spec/mongo/crypt/auto_encrypter_spec.rb +14 -12
- data/spec/mongo/crypt/data_key_context_spec.rb +3 -1
- data/spec/mongo/crypt/explicit_encryption_context_spec.rb +2 -2
- data/spec/mongo/crypt/handle_spec.rb +1 -1
- data/spec/mongo/cursor_spec.rb +26 -9
- data/spec/mongo/error/operation_failure_heavy_spec.rb +2 -2
- data/spec/mongo/operation/context_spec.rb +79 -0
- data/spec/mongo/operation/create/op_msg_spec.rb +106 -110
- data/spec/mongo/operation/delete/op_msg_spec.rb +6 -5
- data/spec/mongo/operation/find/op_msg_spec.rb +66 -0
- data/spec/mongo/operation/get_more/op_msg_spec.rb +65 -0
- data/spec/mongo/operation/insert/op_msg_spec.rb +128 -131
- data/spec/mongo/operation/shared/csot/examples.rb +113 -0
- data/spec/mongo/query_cache_spec.rb +243 -225
- data/spec/mongo/retryable_spec.rb +1 -0
- data/spec/mongo/server/round_trip_time_calculator_spec.rb +120 -0
- data/spec/mongo/socket/ssl_spec.rb +0 -10
- data/spec/runners/change_streams/test.rb +2 -2
- data/spec/runners/crud/operation.rb +1 -1
- data/spec/runners/crud/verifier.rb +3 -1
- data/spec/runners/transactions/operation.rb +4 -6
- data/spec/runners/unified/ambiguous_operations.rb +13 -0
- data/spec/runners/unified/assertions.rb +4 -0
- data/spec/runners/unified/change_stream_operations.rb +14 -24
- data/spec/runners/unified/crud_operations.rb +82 -59
- data/spec/runners/unified/ddl_operations.rb +38 -7
- data/spec/runners/unified/grid_fs_operations.rb +37 -2
- data/spec/runners/unified/support_operations.rb +43 -4
- data/spec/runners/unified/test.rb +22 -10
- data/spec/runners/unified.rb +1 -1
- data/spec/solo/clean_exit_spec.rb +2 -0
- data/spec/spec_tests/client_side_operations_timeout_spec.rb +15 -0
- data/spec/spec_tests/data/change_streams_unified/change-streams-clusterTime.yml +3 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-disambiguatedPaths.yml +3 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-errors.yml +3 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-pre_and_post_images.yml +1 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-resume-allowlist.yml +1 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-resume-errorLabels.yml +1 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +1 -1
- data/spec/spec_tests/data/client_side_encryption/badQueries.yml +2 -1
- data/spec/spec_tests/data/client_side_encryption/timeoutMS.yml +67 -0
- data/spec/spec_tests/data/client_side_operations_timeout/bulkWrite.yml +87 -0
- data/spec/spec_tests/data/client_side_operations_timeout/change-streams.yml +358 -0
- data/spec/spec_tests/data/client_side_operations_timeout/close-cursors.yml +129 -0
- data/spec/spec_tests/data/client_side_operations_timeout/command-execution.yml +250 -0
- data/spec/spec_tests/data/client_side_operations_timeout/convenient-transactions.yml +113 -0
- data/spec/spec_tests/data/client_side_operations_timeout/cursors.yml +70 -0
- data/spec/spec_tests/data/client_side_operations_timeout/deprecated-options.yml +3982 -0
- data/spec/spec_tests/data/client_side_operations_timeout/error-transformations.yml +96 -0
- data/spec/spec_tests/data/client_side_operations_timeout/global-timeoutMS.yml +3236 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-advanced.yml +207 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-delete.yml +152 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-download.yml +182 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-find.yml +100 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-upload.yml +249 -0
- data/spec/spec_tests/data/client_side_operations_timeout/legacy-timeouts.yml +204 -0
- data/spec/spec_tests/data/client_side_operations_timeout/non-tailable-cursors.yml +307 -0
- data/spec/spec_tests/data/client_side_operations_timeout/override-collection-timeoutMS.yml +1877 -0
- data/spec/spec_tests/data/client_side_operations_timeout/override-operation-timeoutMS.yml +1918 -0
- data/spec/spec_tests/data/client_side_operations_timeout/retryability-legacy-timeouts.yml +1676 -0
- data/spec/spec_tests/data/client_side_operations_timeout/retryability-timeoutMS.yml +2824 -0
- data/spec/spec_tests/data/client_side_operations_timeout/sessions-inherit-timeoutMS.yml +168 -0
- data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-operation-timeoutMS.yml +171 -0
- data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-timeoutMS.yml +168 -0
- data/spec/spec_tests/data/client_side_operations_timeout/tailable-awaitData.yml +247 -0
- data/spec/spec_tests/data/client_side_operations_timeout/tailable-non-awaitData.yml +181 -0
- data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +4 -0
- data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +4 -0
- data/spec/spec_tests/data/crud_unified/find-test-all-options.yml +29 -0
- data/spec/spec_tests/server_selection_rtt_spec.rb +6 -6
- data/spec/support/certificates/atlas-ocsp-ca.crt +81 -83
- data/spec/support/certificates/atlas-ocsp.crt +107 -107
- data/spec/support/cluster_tools.rb +3 -3
- data/spec/support/common_shortcuts.rb +2 -2
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-Date.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalNoPrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalPrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoubleNoPrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoublePrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-Int.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-Long.json +1 -1
- data/spec/support/shared/session.rb +2 -2
- data/spec/support/spec_setup.rb +2 -2
- data/spec/support/utils.rb +3 -1
- metadata +78 -91
- data/spec/mongo/server/round_trip_time_averager_spec.rb +0 -48
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Aggregate.yml +0 -242
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Correctness.yml +0 -423
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Delete.yml +0 -183
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-FindOneAndUpdate.yml +0 -240
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-InsertFind.yml +0 -236
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Update.yml +0 -253
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Aggregate.yml +0 -1688
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Correctness.yml +0 -294
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Delete.yml +0 -906
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-FindOneAndUpdate.yml +0 -1685
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-InsertFind.yml +0 -1681
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Update.yml +0 -1698
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Aggregate.yml +0 -330
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Correctness.yml +0 -425
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Delete.yml +0 -227
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-FindOneAndUpdate.yml +0 -328
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-InsertFind.yml +0 -320
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Update.yml +0 -337
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Aggregate.yml +0 -914
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Correctness.yml +0 -293
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Delete.yml +0 -519
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-FindOneAndUpdate.yml +0 -912
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-InsertFind.yml +0 -908
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Update.yml +0 -925
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Aggregate.yml +0 -326
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Correctness.yml +0 -425
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Delete.yml +0 -225
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-FindOneAndUpdate.yml +0 -324
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-InsertFind.yml +0 -320
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Update.yml +0 -339
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Aggregate.yml +0 -242
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Correctness.yml +0 -424
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Delete.yml +0 -183
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-FindOneAndUpdate.yml +0 -240
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-InsertFind.yml +0 -236
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Update.yml +0 -255
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Aggregate.yml +0 -242
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Correctness.yml +0 -423
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Delete.yml +0 -183
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-FindOneAndUpdate.yml +0 -240
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-InsertFind.yml +0 -236
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Update.yml +0 -255
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-WrongType.yml +0 -44
@@ -205,11 +205,18 @@ module Mongo
|
|
205
205
|
|
206
206
|
# The time to wait, in seconds, for a connection to become available.
|
207
207
|
#
|
208
|
+
# @param [ Mongo::Operation:Context | nil ] context Context of the operation
|
209
|
+
# the connection is requested for, if any.
|
210
|
+
#
|
208
211
|
# @return [ Float ] The queue wait timeout.
|
209
212
|
#
|
210
213
|
# @since 2.9.0
|
211
|
-
def wait_timeout
|
212
|
-
|
214
|
+
def wait_timeout(context = nil)
|
215
|
+
if context&.remaining_timeout_sec.nil?
|
216
|
+
options[:wait_timeout] || DEFAULT_WAIT_TIMEOUT
|
217
|
+
else
|
218
|
+
context&.remaining_timeout_sec
|
219
|
+
end
|
213
220
|
end
|
214
221
|
|
215
222
|
# The maximum seconds a socket can remain idle since it has been
|
@@ -345,6 +352,10 @@ module Mongo
|
|
345
352
|
# The returned connection counts toward the pool's max size. When the
|
346
353
|
# caller is finished using the connection, the connection should be
|
347
354
|
# checked back in via the check_in method.
|
355
|
+
# @param [ Integer | nil ] :connection_global_id The global id for the
|
356
|
+
# connection to check out.
|
357
|
+
# @param [ Mongo::Operation:Context | nil ] :context Context of the operation
|
358
|
+
# the connection is requested for, if any.
|
348
359
|
#
|
349
360
|
# @return [ Mongo::Server::Connection ] The checked out connection.
|
350
361
|
# @raise [ Error::PoolClosedError ] If the pool has been closed.
|
@@ -352,7 +363,7 @@ module Mongo
|
|
352
363
|
# and remains so for longer than the wait timeout.
|
353
364
|
#
|
354
365
|
# @since 2.9.0
|
355
|
-
def check_out(connection_global_id: nil)
|
366
|
+
def check_out(connection_global_id: nil, context: nil)
|
356
367
|
check_invariants
|
357
368
|
|
358
369
|
publish_cmap_event(
|
@@ -362,7 +373,9 @@ module Mongo
|
|
362
373
|
raise_if_pool_closed!
|
363
374
|
raise_if_pool_paused_locked!
|
364
375
|
|
365
|
-
connection = retrieve_and_connect_connection(
|
376
|
+
connection = retrieve_and_connect_connection(
|
377
|
+
connection_global_id, context
|
378
|
+
)
|
366
379
|
|
367
380
|
publish_cmap_event(
|
368
381
|
Monitoring::Event::Cmap::ConnectionCheckedOut.new(@server.address, connection.id, self),
|
@@ -698,10 +711,13 @@ module Mongo
|
|
698
711
|
# @return [ Object ] The result of the block.
|
699
712
|
#
|
700
713
|
# @since 2.0.0
|
701
|
-
def with_connection(connection_global_id: nil)
|
714
|
+
def with_connection(connection_global_id: nil, context: nil)
|
702
715
|
raise_if_closed!
|
703
716
|
|
704
|
-
connection = check_out(
|
717
|
+
connection = check_out(
|
718
|
+
connection_global_id: connection_global_id,
|
719
|
+
context: context
|
720
|
+
)
|
705
721
|
yield(connection)
|
706
722
|
rescue Error::SocketError, Error::SocketTimeoutError, Error::ConnectionPerished => e
|
707
723
|
maybe_raise_pool_cleared!(connection, e)
|
@@ -975,9 +991,9 @@ module Mongo
|
|
975
991
|
|
976
992
|
# Attempts to connect (handshake and auth) the connection. If an error is
|
977
993
|
# encountered, closes the connection and raises the error.
|
978
|
-
def connect_connection(connection)
|
994
|
+
def connect_connection(connection, context = nil)
|
979
995
|
begin
|
980
|
-
connection.connect!
|
996
|
+
connection.connect!(context)
|
981
997
|
rescue Exception
|
982
998
|
connection.disconnect!(reason: :error)
|
983
999
|
raise
|
@@ -1242,16 +1258,18 @@ module Mongo
|
|
1242
1258
|
|
1243
1259
|
# Retrieves a connection and connects it.
|
1244
1260
|
#
|
1245
|
-
# @param [ Integer ] connection_global_id The global id for the
|
1261
|
+
# @param [ Integer | nil ] connection_global_id The global id for the
|
1246
1262
|
# connection to check out.
|
1263
|
+
# @param [ Mongo::Operation:Context | nil ] context Context of the operation
|
1264
|
+
# the connection is requested for, if any.
|
1247
1265
|
#
|
1248
1266
|
# @return [ Mongo::Server::Connection ] The checked out connection.
|
1249
1267
|
#
|
1250
1268
|
# @raise [ Error::PoolClosedError ] If the pool has been closed.
|
1251
1269
|
# @raise [ Timeout::Error ] If the connection pool is at maximum size
|
1252
1270
|
# and remains so for longer than the wait timeout.
|
1253
|
-
def retrieve_and_connect_connection(connection_global_id)
|
1254
|
-
deadline = Utils.monotonic_time + wait_timeout
|
1271
|
+
def retrieve_and_connect_connection(connection_global_id, context = nil)
|
1272
|
+
deadline = Utils.monotonic_time + wait_timeout(context)
|
1255
1273
|
connection = nil
|
1256
1274
|
|
1257
1275
|
@lock.synchronize do
|
@@ -1267,7 +1285,7 @@ module Mongo
|
|
1267
1285
|
connection = wait_for_connection(connection_global_id, deadline)
|
1268
1286
|
end
|
1269
1287
|
|
1270
|
-
connect_or_raise(connection) unless connection.connected?
|
1288
|
+
connect_or_raise(connection, context) unless connection.connected?
|
1271
1289
|
|
1272
1290
|
@lock.synchronize do
|
1273
1291
|
@checked_out_connections << connection
|
@@ -1327,8 +1345,8 @@ module Mongo
|
|
1327
1345
|
# cannot be connected.
|
1328
1346
|
# This method also publish corresponding event and ensures that counters
|
1329
1347
|
# and condition variables are updated.
|
1330
|
-
def connect_or_raise(connection)
|
1331
|
-
connect_connection(connection)
|
1348
|
+
def connect_or_raise(connection, context)
|
1349
|
+
connect_connection(connection, context)
|
1332
1350
|
rescue Exception
|
1333
1351
|
# Handshake or authentication failed
|
1334
1352
|
@lock.synchronize do
|
@@ -83,7 +83,7 @@ module Mongo
|
|
83
83
|
# The wire protocol versions that this version of the driver supports.
|
84
84
|
#
|
85
85
|
# @since 2.0.0
|
86
|
-
DRIVER_WIRE_VERSIONS = (6..
|
86
|
+
DRIVER_WIRE_VERSIONS = (6..25).freeze
|
87
87
|
|
88
88
|
# Create the methods for each mapping to tell if they are supported.
|
89
89
|
#
|
@@ -209,8 +209,8 @@ module Mongo
|
|
209
209
|
# @param [ Hash ] config The result of the hello command.
|
210
210
|
# @param [ Float ] average_round_trip_time The moving average time (sec) the hello
|
211
211
|
# command took to complete.
|
212
|
-
# @param [ Float ]
|
213
|
-
#
|
212
|
+
# @param [ Float ] minimum_round_trip_time The minimum round trip time
|
213
|
+
# of ten last hello commands.
|
214
214
|
# @param [ true | false ] load_balancer Whether the server is treated as
|
215
215
|
# a load balancer.
|
216
216
|
# @param [ true | false ] force_load_balancer Whether the server is
|
@@ -218,7 +218,8 @@ module Mongo
|
|
218
218
|
#
|
219
219
|
# @api private
|
220
220
|
def initialize(address, config = {}, average_round_trip_time: nil,
|
221
|
-
|
221
|
+
minimum_round_trip_time: 0, load_balancer: false,
|
222
|
+
force_load_balancer: false
|
222
223
|
)
|
223
224
|
@address = address
|
224
225
|
@config = config
|
@@ -226,6 +227,7 @@ module Mongo
|
|
226
227
|
@force_load_balancer = !!force_load_balancer
|
227
228
|
@features = Features.new(wire_versions, me || @address.to_s)
|
228
229
|
@average_round_trip_time = average_round_trip_time
|
230
|
+
@minimum_round_trip_time = minimum_round_trip_time
|
229
231
|
@last_update_time = Time.now.freeze
|
230
232
|
@last_update_monotime = Utils.monotonic_time
|
231
233
|
|
@@ -302,6 +304,10 @@ module Mongo
|
|
302
304
|
# @return [ Float ] The moving average time the hello call took to complete.
|
303
305
|
attr_reader :average_round_trip_time
|
304
306
|
|
307
|
+
# @return [ Float ] The minimum time from the ten last hello calls took
|
308
|
+
# to complete.
|
309
|
+
attr_reader :minimum_round_trip_time
|
310
|
+
|
305
311
|
# Returns whether this server is an arbiter, per the SDAM spec.
|
306
312
|
#
|
307
313
|
# @example Is the server an arbiter?
|
@@ -723,8 +729,7 @@ module Mongo
|
|
723
729
|
|
724
730
|
# @api private
|
725
731
|
def ok?
|
726
|
-
config[Operation::Result::OK]
|
727
|
-
config[Operation::Result::OK] == 1 || false
|
732
|
+
config[Operation::Result::OK] == 1
|
728
733
|
end
|
729
734
|
|
730
735
|
# Get the range of supported wire versions for the server.
|
@@ -802,6 +807,14 @@ module Mongo
|
|
802
807
|
!!(address.to_s.downcase != me.downcase if me)
|
803
808
|
end
|
804
809
|
|
810
|
+
# Whether this description is from a mongocryptd server.
|
811
|
+
#
|
812
|
+
# @return [ true, false ] Whether this description is from a mongocryptd
|
813
|
+
# server.
|
814
|
+
def mongocryptd?
|
815
|
+
ok? && config['iscryptd'] == true
|
816
|
+
end
|
817
|
+
|
805
818
|
# opTime in lastWrite subdocument of the hello response.
|
806
819
|
#
|
807
820
|
# @return [ BSON::Timestamp ] The timestamp.
|
data/lib/mongo/server/monitor.rb
CHANGED
@@ -237,8 +237,11 @@ module Mongo
|
|
237
237
|
@sdam_mutex.synchronize do
|
238
238
|
old_description = server.description
|
239
239
|
|
240
|
-
new_description = Description.new(
|
241
|
-
|
240
|
+
new_description = Description.new(
|
241
|
+
server.address,
|
242
|
+
result,
|
243
|
+
average_round_trip_time: server.round_trip_time_calculator.average_round_trip_time,
|
244
|
+
minimum_round_trip_time: server.round_trip_time_calculator.minimum_round_trip_time
|
242
245
|
)
|
243
246
|
|
244
247
|
server.cluster.run_sdam_flow(server.description, new_description, awaited: awaited, scan_error: scan_error)
|
@@ -306,7 +309,7 @@ module Mongo
|
|
306
309
|
end
|
307
310
|
|
308
311
|
if @connection
|
309
|
-
result = server.
|
312
|
+
result = server.round_trip_time_calculator.measure do
|
310
313
|
begin
|
311
314
|
doc = @connection.check_document
|
312
315
|
cmd = Protocol::Query.new(
|
@@ -323,7 +326,7 @@ module Mongo
|
|
323
326
|
else
|
324
327
|
connection = Connection.new(server.address, options)
|
325
328
|
connection.connect!
|
326
|
-
result = server.
|
329
|
+
result = server.round_trip_time_calculator.measure do
|
327
330
|
connection.handshake!
|
328
331
|
end
|
329
332
|
@connection = connection
|
@@ -120,7 +120,7 @@ module Mongo
|
|
120
120
|
#
|
121
121
|
# @return [ Mongo::Protocol::Reply ] Deserialized server response.
|
122
122
|
def get_handshake_response(hello_command)
|
123
|
-
@server.
|
123
|
+
@server.round_trip_time_calculator.measure do
|
124
124
|
add_server_diagnostics do
|
125
125
|
socket.write(hello_command.serialize.to_s)
|
126
126
|
Protocol::Message.deserialize(socket, Protocol::Message::MAX_MESSAGE_SIZE)
|
@@ -168,7 +168,11 @@ module Mongo
|
|
168
168
|
doc['serviceId'] ||= "fake:#{rand(2**32-1)+1}"
|
169
169
|
end
|
170
170
|
|
171
|
-
post_handshake(
|
171
|
+
post_handshake(
|
172
|
+
doc,
|
173
|
+
@server.round_trip_time_calculator.average_round_trip_time,
|
174
|
+
@server.round_trip_time_calculator.minimum_round_trip_time
|
175
|
+
)
|
172
176
|
|
173
177
|
doc
|
174
178
|
end
|
@@ -218,7 +222,7 @@ module Mongo
|
|
218
222
|
#
|
219
223
|
# @return [ Server::Description ] The server description calculated from
|
220
224
|
# the handshake response for this particular connection.
|
221
|
-
def post_handshake(response, average_rtt)
|
225
|
+
def post_handshake(response, average_rtt, minimum_rtt)
|
222
226
|
if response["ok"] == 1
|
223
227
|
# Auth mechanism is entirely dependent on the contents of
|
224
228
|
# hello response *for this connection*.
|
@@ -18,20 +18,30 @@
|
|
18
18
|
module Mongo
|
19
19
|
class Server
|
20
20
|
# @api private
|
21
|
-
class
|
21
|
+
class RoundTripTimeCalculator
|
22
22
|
|
23
23
|
# The weighting factor (alpha) for calculating the average moving
|
24
24
|
# round trip time.
|
25
25
|
RTT_WEIGHT_FACTOR = 0.2.freeze
|
26
26
|
private_constant :RTT_WEIGHT_FACTOR
|
27
27
|
|
28
|
+
RTT_SAMPLES_FOR_MINIMUM = 10
|
29
|
+
private_constant :RTT_SAMPLES_FOR_MINIMUM
|
30
|
+
|
31
|
+
MIN_SAMPLES = 3
|
32
|
+
private_constant :MIN_SAMPLES
|
33
|
+
|
28
34
|
def initialize
|
29
35
|
@last_round_trip_time = nil
|
30
36
|
@average_round_trip_time = nil
|
37
|
+
@minimum_round_trip_time = 0
|
38
|
+
@lock = Mutex.new
|
39
|
+
@rtts = []
|
31
40
|
end
|
32
41
|
|
33
42
|
attr_reader :last_round_trip_time
|
34
43
|
attr_reader :average_round_trip_time
|
44
|
+
attr_reader :minimum_round_trip_time
|
35
45
|
|
36
46
|
def measure
|
37
47
|
start = Utils.monotonic_time
|
@@ -44,14 +54,17 @@ module Mongo
|
|
44
54
|
rescue Error, Error::AuthError => exc
|
45
55
|
# For other errors, RTT is valid.
|
46
56
|
end
|
47
|
-
|
57
|
+
last_rtt = Utils.monotonic_time - start
|
48
58
|
|
49
59
|
# If hello fails, we need to return the last round trip time
|
50
60
|
# because it is used in the heartbeat failed SDAM event,
|
51
61
|
# but we must not update the round trip time recorded in the server.
|
52
62
|
unless exc
|
53
|
-
@last_round_trip_time =
|
54
|
-
|
63
|
+
@last_round_trip_time = last_rtt
|
64
|
+
@lock.synchronize do
|
65
|
+
update_average_round_trip_time
|
66
|
+
update_minimum_round_trip_time
|
67
|
+
end
|
55
68
|
end
|
56
69
|
|
57
70
|
if exc
|
@@ -61,9 +74,6 @@ module Mongo
|
|
61
74
|
end
|
62
75
|
end
|
63
76
|
|
64
|
-
private
|
65
|
-
|
66
|
-
# This method is separate for testing purposes.
|
67
77
|
def update_average_round_trip_time
|
68
78
|
@average_round_trip_time = if average_round_trip_time
|
69
79
|
RTT_WEIGHT_FACTOR * last_round_trip_time + (1 - RTT_WEIGHT_FACTOR) * average_round_trip_time
|
@@ -71,6 +81,14 @@ module Mongo
|
|
71
81
|
last_round_trip_time
|
72
82
|
end
|
73
83
|
end
|
84
|
+
|
85
|
+
def update_minimum_round_trip_time
|
86
|
+
@rtts.push(last_round_trip_time) unless last_round_trip_time.nil?
|
87
|
+
@minimum_round_trip_time = 0 and return if @rtts.size < MIN_SAMPLES
|
88
|
+
|
89
|
+
@rtts.shift if @rtts.size > RTT_SAMPLES_FOR_MINIMUM
|
90
|
+
@minimum_round_trip_time = @rtts.compact.min
|
91
|
+
end
|
74
92
|
end
|
75
93
|
end
|
76
94
|
end
|
data/lib/mongo/server.rb
CHANGED
@@ -80,7 +80,7 @@ module Mongo
|
|
80
80
|
include Id
|
81
81
|
end
|
82
82
|
@scan_semaphore = DistinguishingSemaphore.new
|
83
|
-
@
|
83
|
+
@round_trip_time_calculator = RoundTripTimeCalculator.new
|
84
84
|
@description = Description.new(address, {},
|
85
85
|
load_balancer: !!@options[:load_balancer],
|
86
86
|
force_load_balancer: force_load_balancer?,
|
@@ -197,6 +197,7 @@ module Mongo
|
|
197
197
|
:max_message_size,
|
198
198
|
:tags,
|
199
199
|
:average_round_trip_time,
|
200
|
+
:minimum_round_trip_time,
|
200
201
|
:mongos?,
|
201
202
|
:other?,
|
202
203
|
:primary?,
|
@@ -228,9 +229,9 @@ module Mongo
|
|
228
229
|
# @api private
|
229
230
|
attr_reader :scan_semaphore
|
230
231
|
|
231
|
-
# @return [
|
232
|
+
# @return [ RoundTripTimeCalculator ] Round trip time calculator object.
|
232
233
|
# @api private
|
233
|
-
attr_reader :
|
234
|
+
attr_reader :round_trip_time_calculator
|
234
235
|
|
235
236
|
# Is this server equal to another?
|
236
237
|
#
|
@@ -490,8 +491,12 @@ module Mongo
|
|
490
491
|
# @return [ Object ] The result of the block execution.
|
491
492
|
#
|
492
493
|
# @since 2.3.0
|
493
|
-
def with_connection(connection_global_id: nil, &block)
|
494
|
-
pool.with_connection(
|
494
|
+
def with_connection(connection_global_id: nil, context: nil, &block)
|
495
|
+
pool.with_connection(
|
496
|
+
connection_global_id: connection_global_id,
|
497
|
+
context: context,
|
498
|
+
&block
|
499
|
+
)
|
495
500
|
end
|
496
501
|
|
497
502
|
# Handle handshake failure.
|
@@ -697,5 +702,5 @@ require 'mongo/server/connection'
|
|
697
702
|
require 'mongo/server/connection_pool'
|
698
703
|
require 'mongo/server/description'
|
699
704
|
require 'mongo/server/monitor'
|
700
|
-
require 'mongo/server/
|
705
|
+
require 'mongo/server/round_trip_time_calculator'
|
701
706
|
require 'mongo/server/push_monitor'
|
@@ -33,11 +33,11 @@ module Mongo
|
|
33
33
|
#
|
34
34
|
# @option options [ Integer ] :local_threshold The local threshold boundary for
|
35
35
|
# nearest selection in seconds.
|
36
|
-
# @option options [ Integer ] max_staleness The maximum replication lag,
|
36
|
+
# @option options [ Integer ] :max_staleness The maximum replication lag,
|
37
37
|
# in seconds, that a secondary can suffer and still be eligible for a read.
|
38
38
|
# A value of -1 is treated identically to nil, which is to not
|
39
39
|
# have a maximum staleness.
|
40
|
-
# @option options [ Hash | nil ] hedge A Hash specifying whether to enable hedged
|
40
|
+
# @option options [ Hash | nil ] :hedge A Hash specifying whether to enable hedged
|
41
41
|
# reads on the server. Hedged reads are not enabled by default. When
|
42
42
|
# specifying this option, it must be in the format: { enabled: true },
|
43
43
|
# where the value of the :enabled key is a boolean value.
|
@@ -168,6 +168,8 @@ module Mongo
|
|
168
168
|
# be selected from only if no other servers are available. This is
|
169
169
|
# used to avoid selecting the same server twice in a row when
|
170
170
|
# retrying a command.
|
171
|
+
# @param [ Float | nil ] :timeout Timeout in seconds for the operation,
|
172
|
+
# if any.
|
171
173
|
#
|
172
174
|
# @return [ Mongo::Server ] A server matching the server preference.
|
173
175
|
#
|
@@ -178,21 +180,35 @@ module Mongo
|
|
178
180
|
# lint mode is enabled.
|
179
181
|
#
|
180
182
|
# @since 2.0.0
|
181
|
-
def select_server(
|
182
|
-
|
183
|
+
def select_server(
|
184
|
+
cluster,
|
185
|
+
ping = nil,
|
186
|
+
session = nil,
|
187
|
+
write_aggregation: false,
|
188
|
+
deprioritized: [],
|
189
|
+
timeout: nil
|
190
|
+
)
|
191
|
+
select_server_impl(cluster, ping, session, write_aggregation, deprioritized, timeout).tap do |server|
|
183
192
|
if Lint.enabled? && !server.pool.ready?
|
184
193
|
raise Error::LintError, 'Server selector returning a server with a pool which is not ready'
|
185
194
|
end
|
186
195
|
end
|
187
196
|
end
|
188
197
|
|
189
|
-
# Parameters and return values are the same as for select_server
|
190
|
-
|
198
|
+
# Parameters and return values are the same as for select_server, only
|
199
|
+
# the +timeout+ param is renamed to +csot_timeout+.
|
200
|
+
private def select_server_impl(cluster, ping, session, write_aggregation, deprioritized, csot_timeout)
|
191
201
|
if cluster.topology.is_a?(Cluster::Topology::LoadBalanced)
|
192
202
|
return cluster.servers.first
|
193
203
|
end
|
194
204
|
|
195
|
-
|
205
|
+
timeout = cluster.options[:server_selection_timeout] || SERVER_SELECTION_TIMEOUT
|
206
|
+
|
207
|
+
server_selection_timeout = if csot_timeout && csot_timeout > 0
|
208
|
+
[timeout, csot_timeout].min
|
209
|
+
else
|
210
|
+
timeout
|
211
|
+
end
|
196
212
|
|
197
213
|
# Special handling for zero timeout: if we have to select a server,
|
198
214
|
# and the timeout is zero, fail immediately (since server selection
|
@@ -638,9 +654,9 @@ module Mongo
|
|
638
654
|
# state resulting from SDAM will immediately wake up this method and
|
639
655
|
# cause it to return.
|
640
656
|
#
|
641
|
-
# If the cluster
|
657
|
+
# If the cluster does not have a server selection semaphore, waits
|
642
658
|
# the smaller of 0.25 seconds and the specified remaining time.
|
643
|
-
# This functionality is provided for backwards
|
659
|
+
# This functionality is provided for backwards compatibility only for
|
644
660
|
# applications directly invoking the server selection process.
|
645
661
|
# If lint mode is enabled and the cluster does not have a server
|
646
662
|
# selection semaphore, Error::LintError will be raised.
|
data/lib/mongo/session.rb
CHANGED
@@ -57,6 +57,12 @@ module Mongo
|
|
57
57
|
#
|
58
58
|
# @option options [ true|false ] :causal_consistency Whether to enable
|
59
59
|
# causal consistency for this session.
|
60
|
+
# @option options [ Integer ] :default_timeout_ms The timeoutMS value for
|
61
|
+
# the following operations executed on the session:
|
62
|
+
# - commitTransaction
|
63
|
+
# - abortTransaction
|
64
|
+
# - withTransaction
|
65
|
+
# - endSession
|
60
66
|
# @option options [ Hash ] :default_transaction_options Options to pass
|
61
67
|
# to start_transaction by default, can contain any of the options that
|
62
68
|
# start_transaction accepts.
|
@@ -96,6 +102,7 @@ module Mongo
|
|
96
102
|
@options = options.dup.freeze
|
97
103
|
@cluster_time = nil
|
98
104
|
@state = NO_TRANSACTION_STATE
|
105
|
+
@with_transaction_deadline = nil
|
99
106
|
end
|
100
107
|
|
101
108
|
# @return [ Hash ] The options for this session.
|
@@ -438,9 +445,21 @@ module Mongo
|
|
438
445
|
# progress or if the write concern is unacknowledged.
|
439
446
|
#
|
440
447
|
# @since 2.7.0
|
441
|
-
def with_transaction(options=nil)
|
442
|
-
|
443
|
-
|
448
|
+
def with_transaction(options = nil)
|
449
|
+
if timeout_ms = (options || {})[:timeout_ms]
|
450
|
+
timeout_sec = timeout_ms / 1_000.0
|
451
|
+
deadline = Utils.monotonic_time + timeout_sec
|
452
|
+
@with_transaction_deadline = deadline
|
453
|
+
elsif default_timeout_ms = @options[:default_timeout_ms]
|
454
|
+
timeout_sec = default_timeout_ms / 1_000.0
|
455
|
+
deadline = Utils.monotonic_time + timeout_sec
|
456
|
+
@with_transaction_deadline = deadline
|
457
|
+
elsif @client.timeout_sec
|
458
|
+
deadline = Utils.monotonic_time + @client.timeout_sec
|
459
|
+
@with_transaction_deadline = deadline
|
460
|
+
else
|
461
|
+
deadline = Utils.monotonic_time + 120
|
462
|
+
end
|
444
463
|
transaction_in_progress = false
|
445
464
|
loop do
|
446
465
|
commit_options = {}
|
@@ -454,6 +473,7 @@ module Mongo
|
|
454
473
|
rescue Exception => e
|
455
474
|
if within_states?(STARTING_TRANSACTION_STATE, TRANSACTION_IN_PROGRESS_STATE)
|
456
475
|
log_warn("Aborting transaction due to #{e.class}: #{e}")
|
476
|
+
@with_transaction_deadline = nil
|
457
477
|
abort_transaction
|
458
478
|
transaction_in_progress = false
|
459
479
|
end
|
@@ -481,7 +501,7 @@ module Mongo
|
|
481
501
|
rescue Mongo::Error => e
|
482
502
|
if e.label?('UnknownTransactionCommitResult')
|
483
503
|
if Utils.monotonic_time >= deadline ||
|
484
|
-
e.is_a?(Error::OperationFailure) && e.max_time_ms_expired?
|
504
|
+
e.is_a?(Error::OperationFailure::Family) && e.max_time_ms_expired?
|
485
505
|
then
|
486
506
|
transaction_in_progress = false
|
487
507
|
raise
|
@@ -522,9 +542,10 @@ module Mongo
|
|
522
542
|
log_warn('with_transaction callback broke out of with_transaction loop, aborting transaction')
|
523
543
|
begin
|
524
544
|
abort_transaction
|
525
|
-
rescue Error::OperationFailure, Error::InvalidTransactionOperation
|
545
|
+
rescue Error::OperationFailure::Family, Error::InvalidTransactionOperation
|
526
546
|
end
|
527
547
|
end
|
548
|
+
@with_transaction_deadline = nil
|
528
549
|
end
|
529
550
|
|
530
551
|
# Places subsequent operations in this session into a new transaction.
|
@@ -539,6 +560,7 @@ module Mongo
|
|
539
560
|
#
|
540
561
|
# @option options [ Integer ] :max_commit_time_ms The maximum amount of
|
541
562
|
# time to allow a single commitTransaction command to run, in milliseconds.
|
563
|
+
# This options is deprecated, use :timeout_ms instead.
|
542
564
|
# @option options [ Hash ] :read_concern The read concern options hash,
|
543
565
|
# with the following optional keys:
|
544
566
|
# - *:level* -- the read preference level as a symbol; valid values
|
@@ -549,6 +571,10 @@ module Mongo
|
|
549
571
|
# items:
|
550
572
|
# - *:mode* -- read preference specified as a symbol; the only valid value is
|
551
573
|
# *:primary*.
|
574
|
+
# @option options [ Integer ] :timeout_ms The operation timeout in milliseconds.
|
575
|
+
# Must be a non-negative integer. An explicit value of 0 means infinite.
|
576
|
+
# The default value is unset which means the value is inherited from
|
577
|
+
# the client.
|
552
578
|
#
|
553
579
|
# @raise [ Error::InvalidTransactionOperation ] If a transaction is already in
|
554
580
|
# progress or if the write concern is unacknowledged.
|
@@ -611,6 +637,10 @@ module Mongo
|
|
611
637
|
#
|
612
638
|
# @option options :write_concern [ nil | WriteConcern::Base ] The write
|
613
639
|
# concern to use for this operation.
|
640
|
+
# @option options [ Integer ] :timeout_ms The operation timeout in milliseconds.
|
641
|
+
# Must be a non-negative integer. An explicit value of 0 means infinite.
|
642
|
+
# The default value is unset which means the value is inherited from
|
643
|
+
# the client.
|
614
644
|
#
|
615
645
|
# @raise [ Error::InvalidTransactionOperation ] If there is no active transaction.
|
616
646
|
#
|
@@ -647,7 +677,11 @@ module Mongo
|
|
647
677
|
write_concern = WriteConcern.get(write_concern)
|
648
678
|
end
|
649
679
|
|
650
|
-
context = Operation::Context.new(
|
680
|
+
context = Operation::Context.new(
|
681
|
+
client: @client,
|
682
|
+
session: self,
|
683
|
+
operation_timeouts: operation_timeouts(options)
|
684
|
+
)
|
651
685
|
write_with_retry(write_concern, ending_transaction: true,
|
652
686
|
context: context,
|
653
687
|
) do |connection, txn_num, context|
|
@@ -685,10 +719,15 @@ module Mongo
|
|
685
719
|
# @example Abort the transaction.
|
686
720
|
# session.abort_transaction
|
687
721
|
#
|
722
|
+
# @option options [ Integer ] :timeout_ms The operation timeout in milliseconds.
|
723
|
+
# Must be a non-negative integer. An explicit value of 0 means infinite.
|
724
|
+
# The default value is unset which means the value is inherited from
|
725
|
+
# the client.
|
726
|
+
#
|
688
727
|
# @raise [ Error::InvalidTransactionOperation ] If there is no active transaction.
|
689
728
|
#
|
690
729
|
# @since 2.6.0
|
691
|
-
def abort_transaction
|
730
|
+
def abort_transaction(options = nil)
|
692
731
|
QueryCache.clear
|
693
732
|
|
694
733
|
check_if_ended!
|
@@ -705,10 +744,16 @@ module Mongo
|
|
705
744
|
Mongo::Error::InvalidTransactionOperation.cannot_call_twice_msg(:abortTransaction))
|
706
745
|
end
|
707
746
|
|
747
|
+
options ||= {}
|
748
|
+
|
708
749
|
begin
|
709
750
|
unless starting_transaction?
|
710
751
|
@aborting_transaction = true
|
711
|
-
context = Operation::Context.new(
|
752
|
+
context = Operation::Context.new(
|
753
|
+
client: @client,
|
754
|
+
session: self,
|
755
|
+
operation_timeouts: operation_timeouts(options)
|
756
|
+
)
|
712
757
|
write_with_retry(txn_options[:write_concern],
|
713
758
|
ending_transaction: true, context: context,
|
714
759
|
) do |connection, txn_num, context|
|
@@ -898,7 +943,7 @@ module Mongo
|
|
898
943
|
#
|
899
944
|
# @since 2.6.0
|
900
945
|
# @api private
|
901
|
-
def add_txn_opts!(command, read)
|
946
|
+
def add_txn_opts!(command, read, context)
|
902
947
|
command.tap do |c|
|
903
948
|
# The read concern should be added to any command that starts a transaction.
|
904
949
|
if starting_transaction?
|
@@ -952,6 +997,14 @@ module Mongo
|
|
952
997
|
if c[:writeConcern] && c[:writeConcern][:w] && c[:writeConcern][:w].is_a?(Symbol)
|
953
998
|
c[:writeConcern][:w] = c[:writeConcern][:w].to_s
|
954
999
|
end
|
1000
|
+
|
1001
|
+
# Ignore wtimeout if csot
|
1002
|
+
if context&.csot?
|
1003
|
+
c[:writeConcern]&.delete(:wtimeout)
|
1004
|
+
end
|
1005
|
+
|
1006
|
+
# We must not send an empty (server default) write concern.
|
1007
|
+
c.delete(:writeConcern) if c[:writeConcern]&.empty?
|
955
1008
|
end
|
956
1009
|
end
|
957
1010
|
|
@@ -1138,6 +1191,8 @@ module Mongo
|
|
1138
1191
|
# @api private
|
1139
1192
|
attr_accessor :snapshot_timestamp
|
1140
1193
|
|
1194
|
+
attr_reader :with_transaction_deadline
|
1195
|
+
|
1141
1196
|
private
|
1142
1197
|
|
1143
1198
|
# Get the read concern the session will use when starting a transaction.
|
@@ -1217,5 +1272,19 @@ module Mongo
|
|
1217
1272
|
end
|
1218
1273
|
end
|
1219
1274
|
end
|
1275
|
+
|
1276
|
+
def operation_timeouts(opts)
|
1277
|
+
{
|
1278
|
+
inherited_timeout_ms: @client.timeout_ms
|
1279
|
+
}.tap do |result|
|
1280
|
+
if @with_transaction_deadline.nil?
|
1281
|
+
if timeout_ms = opts[:timeout_ms]
|
1282
|
+
result[:operation_timeout_ms] = timeout_ms
|
1283
|
+
elsif default_timeout_ms = options[:default_timeout_ms]
|
1284
|
+
result[:operation_timeout_ms] = default_timeout_ms
|
1285
|
+
end
|
1286
|
+
end
|
1287
|
+
end
|
1288
|
+
end
|
1220
1289
|
end
|
1221
1290
|
end
|