mongo 2.20.1 → 2.21.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
- 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
|