mongo 2.20.0 → 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 +40 -1
- data/Rakefile +59 -23
- 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/config.rb +2 -2
- 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/base_worker.rb +28 -3
- data/lib/mongo/retryable/read_worker.rb +76 -35
- data/lib/mongo/retryable/write_worker.rb +53 -22
- 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 +25 -8
- 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 +131 -18
- 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 -5
- data/lib/mongo.rb +1 -0
- data/mongo.gemspec +8 -11
- 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 +67 -20
- 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/retryable_reads_errors_spec.rb +35 -23
- data/spec/integration/sdam_error_handling_spec.rb +4 -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 -11
- 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_crud_spec.rb +1 -0
- 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/connection_spec.rb +22 -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/fle2v2-BypassQueryAnalysis.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Compact.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-CreateCollection.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-DecryptExistingData.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Delete.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFields-vs-EncryptedFieldsMap.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFields-vs-jsonSchema.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFieldsMap-defaults.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-FindOneAndUpdate.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-InsertFind-Indexed.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-InsertFind-Unindexed.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-MissingKey.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-NoEncryption.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Update.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-validatorAndPartialFieldExpression.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 +6 -0
- data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +6 -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/spec_tests/transactions_unified_spec.rb +2 -1
- data/spec/support/certificates/atlas-ocsp-ca.crt +89 -79
- data/spec/support/certificates/atlas-ocsp.crt +117 -122
- data/spec/support/certificates/retrieve-atlas-cert +1 -1
- 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 +88 -173
- checksums.yaml.gz.sig +0 -0
- data/spec/mongo/server/round_trip_time_averager_spec.rb +0 -48
- data/spec/shared/LICENSE +0 -20
- data/spec/shared/bin/get-mongodb-download-url +0 -17
- data/spec/shared/bin/s3-copy +0 -45
- data/spec/shared/bin/s3-upload +0 -69
- data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
- data/spec/shared/lib/mrss/cluster_config.rb +0 -231
- data/spec/shared/lib/mrss/constraints.rb +0 -378
- data/spec/shared/lib/mrss/docker_runner.rb +0 -298
- data/spec/shared/lib/mrss/eg_config_utils.rb +0 -51
- data/spec/shared/lib/mrss/event_subscriber.rb +0 -210
- data/spec/shared/lib/mrss/lite_constraints.rb +0 -238
- data/spec/shared/lib/mrss/server_version_registry.rb +0 -113
- data/spec/shared/lib/mrss/session_registry.rb +0 -69
- data/spec/shared/lib/mrss/session_registry_legacy.rb +0 -60
- data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
- data/spec/shared/lib/mrss/utils.rb +0 -37
- data/spec/shared/share/Dockerfile.erb +0 -281
- data/spec/shared/share/haproxy-1.conf +0 -16
- data/spec/shared/share/haproxy-2.conf +0 -17
- data/spec/shared/shlib/config.sh +0 -27
- data/spec/shared/shlib/distro.sh +0 -74
- data/spec/shared/shlib/server.sh +0 -417
- data/spec/shared/shlib/set_env.sh +0 -146
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Aggregate.yml +0 -241
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Correctness.yml +0 -422
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Delete.yml +0 -182
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-FindOneAndUpdate.yml +0 -239
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-InsertFind.yml +0 -235
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Update.yml +0 -252
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Aggregate.yml +0 -1687
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Correctness.yml +0 -293
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Delete.yml +0 -905
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-FindOneAndUpdate.yml +0 -1684
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-InsertFind.yml +0 -1680
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Update.yml +0 -1697
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Aggregate.yml +0 -329
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Correctness.yml +0 -424
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Delete.yml +0 -226
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-FindOneAndUpdate.yml +0 -327
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-InsertFind.yml +0 -319
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Update.yml +0 -336
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Aggregate.yml +0 -913
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Correctness.yml +0 -292
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Delete.yml +0 -518
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-FindOneAndUpdate.yml +0 -911
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-InsertFind.yml +0 -907
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Update.yml +0 -924
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Aggregate.yml +0 -325
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Correctness.yml +0 -424
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Delete.yml +0 -224
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-FindOneAndUpdate.yml +0 -323
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-InsertFind.yml +0 -319
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Update.yml +0 -338
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Aggregate.yml +0 -241
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Correctness.yml +0 -423
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Delete.yml +0 -182
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-FindOneAndUpdate.yml +0 -239
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-InsertFind.yml +0 -235
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Update.yml +0 -254
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Aggregate.yml +0 -241
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Correctness.yml +0 -422
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Delete.yml +0 -182
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-FindOneAndUpdate.yml +0 -239
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-InsertFind.yml +0 -235
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Update.yml +0 -254
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-WrongType.yml +0 -43
- data/spec/support/faas/app/aws_lambda/mongodb/Gemfile.lock +0 -19
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -3
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
|
data/lib/mongo/socket/ssl.rb
CHANGED
@@ -142,26 +142,37 @@ module Mongo
|
|
142
142
|
#
|
143
143
|
# @since 2.0.0
|
144
144
|
def connect!
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
145
|
+
sockaddr = ::Socket.pack_sockaddr_in(port, host)
|
146
|
+
connect_timeout = options[:connect_timeout]
|
147
|
+
map_exceptions do
|
148
|
+
if connect_timeout && connect_timeout != 0
|
149
|
+
deadline = Utils.monotonic_time + connect_timeout
|
150
|
+
if BSON::Environment.jruby?
|
151
|
+
# We encounter some strange problems with connect_nonblock for
|
152
|
+
# ssl sockets on JRuby. Therefore, we use the old +Timeout.timeout+
|
153
|
+
# solution, even though it is known to be not very reliable.
|
154
|
+
raise Error::SocketTimeoutError, 'connect_timeout expired' if connect_timeout < 0
|
155
|
+
|
156
|
+
Timeout.timeout(connect_timeout, Error::SocketTimeoutError, "The socket took over #{options[:connect_timeout]} seconds to connect") do
|
157
|
+
connect_without_timeout(sockaddr)
|
158
|
+
end
|
159
|
+
else
|
160
|
+
connect_with_timeout(sockaddr, connect_timeout)
|
155
161
|
end
|
162
|
+
remaining_timeout = deadline - Utils.monotonic_time
|
163
|
+
verify_certificate!(@socket)
|
164
|
+
verify_ocsp_endpoint!(@socket, remaining_timeout)
|
165
|
+
else
|
166
|
+
connect_without_timeout(sockaddr)
|
156
167
|
verify_certificate!(@socket)
|
157
168
|
verify_ocsp_endpoint!(@socket)
|
158
|
-
rescue
|
159
|
-
@socket.close
|
160
|
-
@socket = nil
|
161
|
-
raise
|
162
169
|
end
|
163
|
-
self
|
164
170
|
end
|
171
|
+
self
|
172
|
+
rescue
|
173
|
+
@socket&.close
|
174
|
+
@socket = nil
|
175
|
+
raise
|
165
176
|
end
|
166
177
|
private :connect!
|
167
178
|
|
@@ -182,6 +193,87 @@ module Mongo
|
|
182
193
|
|
183
194
|
private
|
184
195
|
|
196
|
+
# Connects the socket without a timeout provided.
|
197
|
+
#
|
198
|
+
# @param [ String ] sockaddr Address to connect to.
|
199
|
+
def connect_without_timeout(sockaddr)
|
200
|
+
@tcp_socket.connect(sockaddr)
|
201
|
+
@socket = OpenSSL::SSL::SSLSocket.new(@tcp_socket, context)
|
202
|
+
@socket.hostname = @host_name
|
203
|
+
@socket.sync_close = true
|
204
|
+
@socket.connect
|
205
|
+
end
|
206
|
+
|
207
|
+
# Connects the socket with the connect timeout. The timeout applies to
|
208
|
+
# connecting both ssl socket and the underlying tcp socket.
|
209
|
+
#
|
210
|
+
# @param [ String ] sockaddr Address to connect to.
|
211
|
+
def connect_with_timeout(sockaddr, connect_timeout)
|
212
|
+
if connect_timeout <= 0
|
213
|
+
raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
|
214
|
+
end
|
215
|
+
|
216
|
+
deadline = Utils.monotonic_time + connect_timeout
|
217
|
+
connect_tcp_socket_with_timeout(sockaddr, deadline, connect_timeout)
|
218
|
+
connnect_ssl_socket_with_timeout(deadline, connect_timeout)
|
219
|
+
end
|
220
|
+
|
221
|
+
def connect_tcp_socket_with_timeout(sockaddr, deadline, connect_timeout)
|
222
|
+
if deadline <= Utils.monotonic_time
|
223
|
+
raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
|
224
|
+
end
|
225
|
+
begin
|
226
|
+
@tcp_socket.connect_nonblock(sockaddr)
|
227
|
+
rescue IO::WaitWritable
|
228
|
+
with_select_timeout(deadline, connect_timeout) do |select_timeout|
|
229
|
+
IO.select(nil, [@tcp_socket], nil, select_timeout)
|
230
|
+
end
|
231
|
+
retry
|
232
|
+
rescue Errno::EISCONN
|
233
|
+
# Socket is connected, nothing to do.
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
def connnect_ssl_socket_with_timeout(deadline, connect_timeout)
|
238
|
+
if deadline <= Utils.monotonic_time
|
239
|
+
raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
|
240
|
+
end
|
241
|
+
@socket = OpenSSL::SSL::SSLSocket.new(@tcp_socket, context)
|
242
|
+
@socket.hostname = @host_name
|
243
|
+
@socket.sync_close = true
|
244
|
+
|
245
|
+
# We still have time, connecting ssl socket.
|
246
|
+
begin
|
247
|
+
@socket.connect_nonblock
|
248
|
+
rescue IO::WaitReadable, OpenSSL::SSL::SSLErrorWaitReadable
|
249
|
+
with_select_timeout(deadline, connect_timeout) do |select_timeout|
|
250
|
+
IO.select([@socket], nil, nil, select_timeout)
|
251
|
+
end
|
252
|
+
retry
|
253
|
+
rescue IO::WaitWritable, OpenSSL::SSL::SSLErrorWaitWritable
|
254
|
+
with_select_timeout(deadline, connect_timeout) do |select_timeout|
|
255
|
+
IO.select(nil, [@socket], nil, select_timeout)
|
256
|
+
end
|
257
|
+
retry
|
258
|
+
rescue Errno::EISCONN
|
259
|
+
# Socket is connected, nothing to do
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
# Raises +Error::SocketTimeoutError+ exception if deadline reached or the
|
264
|
+
# block returns nil. The block should call +IO.select+ with the
|
265
|
+
# +connect_timeout+ value. It returns nil if the +connect_timeout+ expires.
|
266
|
+
def with_select_timeout(deadline, connect_timeout, &block)
|
267
|
+
select_timeout = deadline - Utils.monotonic_time
|
268
|
+
if select_timeout <= 0
|
269
|
+
raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
|
270
|
+
end
|
271
|
+
rv = block.call(select_timeout)
|
272
|
+
if rv.nil?
|
273
|
+
raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
185
277
|
def verify_certificate?
|
186
278
|
# If ssl_verify_certificate is not present, disable only if
|
187
279
|
# ssl_verify is explicitly set to false.
|
@@ -287,7 +379,7 @@ module Mongo
|
|
287
379
|
# for instance, if there is no newline between two certificates
|
288
380
|
# this code will extract them both but OpenSSL fails in this situation.
|
289
381
|
if cert_text
|
290
|
-
certs = cert_text
|
382
|
+
certs = extract_certs(cert_text)
|
291
383
|
if certs.length > 1
|
292
384
|
context.cert = OpenSSL::X509::Certificate.new(certs.shift)
|
293
385
|
context.extra_chain_cert = certs.map do |cert|
|
@@ -362,7 +454,7 @@ module Mongo
|
|
362
454
|
end
|
363
455
|
end
|
364
456
|
|
365
|
-
def verify_ocsp_endpoint!(socket)
|
457
|
+
def verify_ocsp_endpoint!(socket, timeout = nil)
|
366
458
|
unless verify_ocsp_endpoint?
|
367
459
|
return
|
368
460
|
end
|
@@ -371,7 +463,7 @@ module Mongo
|
|
371
463
|
ca_cert = socket.peer_cert_chain.last
|
372
464
|
|
373
465
|
verifier = OcspVerifier.new(@host_name, cert, ca_cert, context.cert_store,
|
374
|
-
**Utils.shallow_symbolize_keys(options))
|
466
|
+
**Utils.shallow_symbolize_keys(options).merge(timeout: timeout))
|
375
467
|
verifier.verify_with_cache
|
376
468
|
end
|
377
469
|
|
@@ -390,6 +482,27 @@ module Mongo
|
|
390
482
|
hook.call(@context)
|
391
483
|
end
|
392
484
|
end
|
485
|
+
|
486
|
+
BEGIN_CERT = "-----BEGIN CERTIFICATE-----"
|
487
|
+
END_CERT = "-----END CERTIFICATE-----"
|
488
|
+
|
489
|
+
# This was originally a scan + regex, but the regex was particularly
|
490
|
+
# inefficient and was flagged as a concern by static analysis.
|
491
|
+
def extract_certs(text)
|
492
|
+
[].tap do |list|
|
493
|
+
pos = 0
|
494
|
+
|
495
|
+
while (begin_idx = text.index(BEGIN_CERT, pos))
|
496
|
+
end_idx = text.index(END_CERT, begin_idx)
|
497
|
+
break unless end_idx
|
498
|
+
|
499
|
+
end_idx += END_CERT.length
|
500
|
+
list.push(text[begin_idx...end_idx])
|
501
|
+
|
502
|
+
pos = end_idx
|
503
|
+
end
|
504
|
+
end
|
505
|
+
end
|
393
506
|
end
|
394
507
|
end
|
395
508
|
end
|
data/lib/mongo/socket/tcp.rb
CHANGED
@@ -79,16 +79,50 @@ module Mongo
|
|
79
79
|
# @return [ TCP ] The connected socket instance.
|
80
80
|
#
|
81
81
|
# @since 2.0.0
|
82
|
+
# @api private
|
82
83
|
def connect!
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
84
|
+
socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)
|
85
|
+
sockaddr = ::Socket.pack_sockaddr_in(port, host)
|
86
|
+
connect_timeout = options[:connect_timeout]
|
87
|
+
map_exceptions do
|
88
|
+
if connect_timeout && connect_timeout != 0
|
89
|
+
connect_with_timeout(sockaddr, connect_timeout)
|
90
|
+
else
|
91
|
+
connect_without_timeout(sockaddr)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
self
|
95
|
+
end
|
96
|
+
|
97
|
+
# @api private
|
98
|
+
def connect_without_timeout(sockaddr)
|
99
|
+
socket.connect(sockaddr)
|
100
|
+
end
|
101
|
+
|
102
|
+
# @api private
|
103
|
+
def connect_with_timeout(sockaddr, connect_timeout)
|
104
|
+
if connect_timeout <= 0
|
105
|
+
raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
|
106
|
+
end
|
107
|
+
|
108
|
+
deadline = Utils.monotonic_time + connect_timeout
|
109
|
+
begin
|
110
|
+
socket.connect_nonblock(sockaddr)
|
111
|
+
rescue IO::WaitWritable
|
112
|
+
select_timeout = deadline - Utils.monotonic_time
|
113
|
+
if select_timeout <= 0
|
114
|
+
raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
|
115
|
+
end
|
116
|
+
if IO.select(nil, [socket], nil, select_timeout)
|
117
|
+
retry
|
118
|
+
else
|
119
|
+
socket.close
|
120
|
+
raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
|
87
121
|
end
|
88
|
-
|
122
|
+
rescue Errno::EISCONN
|
123
|
+
# Socket is connected, nothing more to do
|
89
124
|
end
|
90
125
|
end
|
91
|
-
private :connect!
|
92
126
|
|
93
127
|
private
|
94
128
|
|