mongo 2.22.0 → 2.24.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/bin/mongo_console +0 -1
- data/lib/mongo/active_support.rb +1 -2
- data/lib/mongo/address/ipv4.rb +3 -6
- data/lib/mongo/address/ipv6.rb +6 -10
- data/lib/mongo/address/unix.rb +1 -4
- data/lib/mongo/address/validator.rb +16 -28
- data/lib/mongo/address.rb +30 -40
- data/lib/mongo/auth/aws/conversation.rb +6 -10
- data/lib/mongo/auth/aws/credentials.rb +0 -1
- data/lib/mongo/auth/aws/credentials_cache.rb +0 -1
- data/lib/mongo/auth/aws/credentials_retriever.rb +45 -59
- data/lib/mongo/auth/aws/request.rb +20 -35
- data/lib/mongo/auth/aws.rb +1 -2
- data/lib/mongo/auth/base.rb +20 -29
- data/lib/mongo/auth/conversation_base.rb +14 -18
- data/lib/mongo/auth/cr/conversation.rb +0 -3
- data/lib/mongo/auth/cr.rb +1 -4
- data/lib/mongo/auth/credential_cache.rb +0 -2
- data/lib/mongo/auth/gssapi/conversation.rb +3 -8
- data/lib/mongo/auth/gssapi.rb +1 -4
- data/lib/mongo/auth/ldap/conversation.rb +0 -3
- data/lib/mongo/auth/ldap.rb +1 -4
- data/lib/mongo/auth/roles.rb +16 -19
- data/lib/mongo/auth/sasl_conversation_base.rb +7 -11
- data/lib/mongo/auth/scram/conversation.rb +2 -5
- data/lib/mongo/auth/scram.rb +5 -10
- data/lib/mongo/auth/scram256/conversation.rb +2 -5
- data/lib/mongo/auth/scram256.rb +1 -3
- data/lib/mongo/auth/scram_conversation_base.rb +18 -24
- data/lib/mongo/auth/stringprep/profiles/sasl.rb +17 -18
- data/lib/mongo/auth/stringprep/tables.rb +2209 -2210
- data/lib/mongo/auth/stringprep/unicode_normalize/normalize.rb +36 -38
- data/lib/mongo/auth/stringprep/unicode_normalize/tables.rb +1142 -1150
- data/lib/mongo/auth/stringprep.rb +9 -12
- data/lib/mongo/auth/user/view.rb +3 -5
- data/lib/mongo/auth/user.rb +14 -24
- data/lib/mongo/auth/x509/conversation.rb +0 -3
- data/lib/mongo/auth/x509.rb +7 -9
- data/lib/mongo/auth.rb +18 -30
- data/lib/mongo/background_thread.rb +9 -17
- data/lib/mongo/bson.rb +0 -2
- data/lib/mongo/bulk_write/combineable.rb +0 -3
- data/lib/mongo/bulk_write/ordered_combiner.rb +1 -3
- data/lib/mongo/bulk_write/result.rb +11 -16
- data/lib/mongo/bulk_write/result_combiner.rb +9 -12
- data/lib/mongo/bulk_write/transformable.rb +16 -19
- data/lib/mongo/bulk_write/unordered_combiner.rb +1 -3
- data/lib/mongo/bulk_write/validatable.rb +11 -18
- data/lib/mongo/bulk_write.rb +76 -91
- data/lib/mongo/caching_cursor.rb +2 -7
- data/lib/mongo/client.rb +267 -276
- data/lib/mongo/client_encryption.rb +4 -5
- data/lib/mongo/cluster/periodic_executor.rb +2 -5
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +21 -29
- data/lib/mongo/cluster/reapers/socket_reaper.rb +1 -6
- data/lib/mongo/cluster/sdam_flow.rb +136 -159
- data/lib/mongo/cluster/topology/base.rb +15 -18
- data/lib/mongo/cluster/topology/load_balanced.rb +24 -14
- data/lib/mongo/cluster/topology/no_replica_set_options.rb +3 -6
- data/lib/mongo/cluster/topology/replica_set_no_primary.rb +20 -23
- data/lib/mongo/cluster/topology/replica_set_with_primary.rb +0 -2
- data/lib/mongo/cluster/topology/sharded.rb +19 -9
- data/lib/mongo/cluster/topology/single.rb +24 -14
- data/lib/mongo/cluster/topology/unknown.rb +20 -10
- data/lib/mongo/cluster/topology.rb +29 -25
- data/lib/mongo/cluster.rb +152 -184
- data/lib/mongo/cluster_time.rb +14 -31
- data/lib/mongo/collection/helpers.rb +5 -8
- data/lib/mongo/collection/view/aggregation/behavior.rb +1 -1
- data/lib/mongo/collection/view/aggregation.rb +10 -12
- data/lib/mongo/collection/view/builder/aggregation.rb +6 -9
- data/lib/mongo/collection/view/builder/map_reduce.rb +18 -17
- data/lib/mongo/collection/view/builder.rb +0 -1
- data/lib/mongo/collection/view/change_stream/retryable.rb +3 -8
- data/lib/mongo/collection/view/change_stream.rb +59 -58
- data/lib/mongo/collection/view/explainable.rb +11 -20
- data/lib/mongo/collection/view/immutable.rb +1 -3
- data/lib/mongo/collection/view/iterable.rb +44 -35
- data/lib/mongo/collection/view/map_reduce.rb +20 -25
- data/lib/mongo/collection/view/readable.rb +96 -94
- data/lib/mongo/collection/view/writable.rb +104 -114
- data/lib/mongo/collection/view.rb +11 -8
- data/lib/mongo/collection.rb +103 -106
- data/lib/mongo/condition_variable.rb +4 -4
- data/lib/mongo/config/options.rb +0 -3
- data/lib/mongo/config/validators/option.rb +3 -5
- data/lib/mongo/config.rb +6 -4
- data/lib/mongo/crypt/auto_decryption_context.rb +9 -3
- data/lib/mongo/crypt/auto_encrypter.rb +34 -43
- data/lib/mongo/crypt/auto_encryption_context.rb +0 -3
- data/lib/mongo/crypt/binary.rb +5 -9
- data/lib/mongo/crypt/binding.rb +150 -156
- data/lib/mongo/crypt/context.rb +20 -17
- data/lib/mongo/crypt/data_key_context.rb +2 -7
- data/lib/mongo/crypt/encryption_io.rb +29 -39
- data/lib/mongo/crypt/explicit_decryption_context.rb +9 -3
- data/lib/mongo/crypt/explicit_encrypter.rb +1 -1
- data/lib/mongo/crypt/explicit_encryption_context.rb +19 -30
- data/lib/mongo/crypt/explicit_encryption_expression_context.rb +0 -2
- data/lib/mongo/crypt/handle.rb +42 -48
- data/lib/mongo/crypt/hooks.rb +12 -15
- data/lib/mongo/crypt/kms/aws/credentials.rb +12 -16
- data/lib/mongo/crypt/kms/aws/master_document.rb +6 -9
- data/lib/mongo/crypt/kms/aws.rb +0 -2
- data/lib/mongo/crypt/kms/azure/credentials_retriever.rb +2 -7
- data/lib/mongo/crypt/kms/azure/master_document.rb +15 -19
- data/lib/mongo/crypt/kms/azure.rb +0 -1
- data/lib/mongo/crypt/kms/credentials.rb +13 -27
- data/lib/mongo/crypt/kms/gcp/credentials.rb +12 -14
- data/lib/mongo/crypt/kms/gcp/credentials_retriever.rb +7 -9
- data/lib/mongo/crypt/kms/gcp/master_document.rb +12 -16
- data/lib/mongo/crypt/kms/gcp.rb +0 -2
- data/lib/mongo/crypt/kms/kmip/credentials.rb +7 -8
- data/lib/mongo/crypt/kms/kmip/master_document.rb +3 -5
- data/lib/mongo/crypt/kms/kmip.rb +0 -1
- data/lib/mongo/crypt/kms/local/credentials.rb +7 -8
- data/lib/mongo/crypt/kms/local/master_document.rb +2 -6
- data/lib/mongo/crypt/kms/local.rb +0 -1
- data/lib/mongo/crypt/kms/master_key_document.rb +11 -15
- data/lib/mongo/crypt/kms.rb +14 -16
- data/lib/mongo/crypt/kms_context.rb +0 -2
- data/lib/mongo/crypt/rewrap_many_data_key_context.rb +2 -7
- data/lib/mongo/crypt/rewrap_many_data_key_result.rb +2 -4
- data/lib/mongo/crypt/status.rb +12 -14
- data/lib/mongo/crypt.rb +0 -1
- data/lib/mongo/csot_timeout_holder.rb +3 -2
- data/lib/mongo/cursor/kill_spec.rb +7 -10
- data/lib/mongo/cursor.rb +74 -64
- data/lib/mongo/cursor_host.rb +8 -10
- data/lib/mongo/database/view.rb +23 -39
- data/lib/mongo/database.rb +68 -65
- data/lib/mongo/dbref.rb +0 -1
- data/lib/mongo/deprecations.rb +98 -0
- data/lib/mongo/distinguishing_semaphore.rb +0 -1
- data/lib/mongo/error/auth_error.rb +0 -2
- data/lib/mongo/error/bad_load_balancer_target.rb +0 -2
- data/lib/mongo/error/bulk_write_error.rb +7 -10
- data/lib/mongo/error/change_stream_resumable.rb +0 -2
- data/lib/mongo/error/client_closed.rb +0 -2
- data/lib/mongo/error/closed_stream.rb +1 -4
- data/lib/mongo/error/connection_check_out_timeout.rb +3 -6
- data/lib/mongo/error/connection_perished.rb +0 -2
- data/lib/mongo/error/connection_unavailable.rb +0 -2
- data/lib/mongo/error/credential_check_error.rb +0 -2
- data/lib/mongo/error/crypt_error.rb +0 -2
- data/lib/mongo/error/extra_file_chunk.rb +1 -4
- data/lib/mongo/error/failed_string_prep_validation.rb +5 -6
- data/lib/mongo/error/file_not_found.rb +0 -3
- data/lib/mongo/error/handshake_error.rb +0 -2
- data/lib/mongo/error/insufficient_iteration_count.rb +1 -4
- data/lib/mongo/error/internal_driver_error.rb +0 -2
- data/lib/mongo/error/invalid_address.rb +0 -2
- data/lib/mongo/error/invalid_application_name.rb +0 -3
- data/lib/mongo/error/invalid_bulk_operation.rb +1 -4
- data/lib/mongo/error/invalid_bulk_operation_type.rb +1 -4
- data/lib/mongo/error/invalid_collection_name.rb +1 -4
- data/lib/mongo/error/invalid_config_option.rb +0 -3
- data/lib/mongo/error/invalid_cursor_operation.rb +0 -2
- data/lib/mongo/error/invalid_database_name.rb +1 -4
- data/lib/mongo/error/invalid_document.rb +1 -4
- data/lib/mongo/error/invalid_file.rb +0 -3
- data/lib/mongo/error/invalid_file_revision.rb +0 -3
- data/lib/mongo/error/invalid_min_pool_size.rb +0 -3
- data/lib/mongo/error/invalid_nonce.rb +0 -3
- data/lib/mongo/error/invalid_read_concern.rb +2 -4
- data/lib/mongo/error/invalid_read_option.rb +0 -3
- data/lib/mongo/error/invalid_replacement_document.rb +2 -5
- data/lib/mongo/error/invalid_server_auth_host.rb +0 -2
- data/lib/mongo/error/invalid_server_auth_response.rb +0 -2
- data/lib/mongo/error/invalid_server_preference.rb +7 -16
- data/lib/mongo/error/invalid_session.rb +1 -4
- data/lib/mongo/error/invalid_signature.rb +0 -3
- data/lib/mongo/error/invalid_transaction_operation.rb +5 -8
- data/lib/mongo/error/invalid_txt_record.rb +0 -2
- data/lib/mongo/error/invalid_update_document.rb +2 -5
- data/lib/mongo/error/invalid_uri.rb +1 -4
- data/lib/mongo/error/invalid_write_concern.rb +2 -5
- data/lib/mongo/error/kms_error.rb +0 -2
- data/lib/mongo/error/labelable.rb +0 -3
- data/lib/mongo/error/lint_error.rb +0 -2
- data/lib/mongo/error/max_bson_size.rb +8 -11
- data/lib/mongo/error/max_message_size.rb +2 -5
- data/lib/mongo/error/mismatched_domain.rb +0 -2
- data/lib/mongo/error/missing_connection.rb +0 -2
- data/lib/mongo/error/missing_file_chunk.rb +0 -3
- data/lib/mongo/error/missing_password.rb +0 -2
- data/lib/mongo/error/missing_resume_token.rb +1 -4
- data/lib/mongo/error/missing_scram_server_signature.rb +2 -4
- data/lib/mongo/error/missing_service_id.rb +0 -2
- data/lib/mongo/error/mongocryptd_spawn_error.rb +0 -2
- data/lib/mongo/error/multi_index_drop.rb +0 -3
- data/lib/mongo/error/need_primary_server.rb +0 -2
- data/lib/mongo/error/no_server_available.rb +3 -8
- data/lib/mongo/error/no_service_connection_available.rb +1 -3
- data/lib/mongo/error/no_srv_records.rb +0 -2
- data/lib/mongo/error/notable.rb +8 -16
- data/lib/mongo/error/operation_failure.rb +22 -35
- data/lib/mongo/error/parser.rb +33 -75
- data/lib/mongo/error/pool_cleared_error.rb +1 -3
- data/lib/mongo/error/pool_closed_error.rb +0 -3
- data/lib/mongo/error/pool_error.rb +0 -3
- data/lib/mongo/error/pool_paused_error.rb +0 -2
- data/lib/mongo/error/raise_original_error.rb +1 -3
- data/lib/mongo/error/read_write_retryable.rb +14 -17
- data/lib/mongo/error/sdam_error_detection.rb +3 -5
- data/lib/mongo/error/server_api_conflict.rb +0 -2
- data/lib/mongo/error/server_certificate_revoked.rb +0 -2
- data/lib/mongo/error/server_not_usable.rb +0 -2
- data/lib/mongo/error/session_ended.rb +1 -3
- data/lib/mongo/error/session_not_materialized.rb +1 -3
- data/lib/mongo/error/sessions_not_supported.rb +1 -4
- data/lib/mongo/error/snapshot_session_invalid_server_version.rb +1 -4
- data/lib/mongo/error/snapshot_session_transaction_prohibited.rb +1 -4
- data/lib/mongo/error/socket_error.rb +0 -2
- data/lib/mongo/error/socket_timeout_error.rb +0 -2
- data/lib/mongo/error/transactions_not_supported.rb +3 -6
- data/lib/mongo/error/unchangeable_collection_option.rb +1 -4
- data/lib/mongo/error/unexpected_chunk_length.rb +0 -3
- data/lib/mongo/error/unexpected_response.rb +1 -4
- data/lib/mongo/error/unknown_payload_type.rb +0 -3
- data/lib/mongo/error/unmet_dependency.rb +0 -2
- data/lib/mongo/error/unsupported_array_filters.rb +3 -24
- data/lib/mongo/error/unsupported_collation.rb +3 -24
- data/lib/mongo/error/unsupported_features.rb +0 -2
- data/lib/mongo/error/unsupported_message_type.rb +0 -2
- data/lib/mongo/error/unsupported_option.rb +19 -21
- data/lib/mongo/error/write_retryable.rb +0 -2
- data/lib/mongo/error.rb +10 -24
- data/lib/mongo/event/base.rb +0 -2
- data/lib/mongo/event/listeners.rb +0 -3
- data/lib/mongo/event/publisher.rb +0 -3
- data/lib/mongo/event/subscriber.rb +0 -4
- data/lib/mongo/event.rb +4 -6
- data/lib/mongo/grid/file/chunk.rb +7 -10
- data/lib/mongo/grid/file/info.rb +20 -24
- data/lib/mongo/grid/file.rb +7 -8
- data/lib/mongo/grid/fs_bucket.rb +40 -48
- data/lib/mongo/grid/stream/read.rb +25 -35
- data/lib/mongo/grid/stream/write.rb +17 -22
- data/lib/mongo/grid/stream.rb +2 -4
- data/lib/mongo/grid.rb +0 -1
- data/lib/mongo/id.rb +0 -1
- data/lib/mongo/index/view.rb +68 -58
- data/lib/mongo/index.rb +7 -10
- data/lib/mongo/lint.rb +31 -37
- data/lib/mongo/loggable.rb +5 -8
- data/lib/mongo/logger.rb +1 -7
- data/lib/mongo/monitoring/cmap_log_subscriber.rb +0 -2
- data/lib/mongo/monitoring/command_log_subscriber.rb +25 -33
- data/lib/mongo/monitoring/event/cmap/base.rb +0 -2
- data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +1 -4
- data/lib/mongo/monitoring/event/cmap/connection_check_out_started.rb +0 -3
- data/lib/mongo/monitoring/event/cmap/connection_checked_in.rb +1 -4
- data/lib/mongo/monitoring/event/cmap/connection_checked_out.rb +2 -5
- data/lib/mongo/monitoring/event/cmap/connection_closed.rb +1 -4
- data/lib/mongo/monitoring/event/cmap/connection_created.rb +1 -4
- data/lib/mongo/monitoring/event/cmap/connection_ready.rb +1 -4
- data/lib/mongo/monitoring/event/cmap/pool_cleared.rb +0 -3
- data/lib/mongo/monitoring/event/cmap/pool_closed.rb +1 -4
- data/lib/mongo/monitoring/event/cmap/pool_created.rb +1 -4
- data/lib/mongo/monitoring/event/cmap/pool_ready.rb +1 -4
- data/lib/mongo/monitoring/event/cmap.rb +0 -1
- data/lib/mongo/monitoring/event/command_failed.rb +5 -9
- data/lib/mongo/monitoring/event/command_started.rb +8 -12
- data/lib/mongo/monitoring/event/command_succeeded.rb +7 -15
- data/lib/mongo/monitoring/event/secure.rb +15 -20
- data/lib/mongo/monitoring/event/server_closed.rb +1 -4
- data/lib/mongo/monitoring/event/server_description_changed.rb +4 -8
- data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +5 -10
- data/lib/mongo/monitoring/event/server_heartbeat_started.rb +1 -4
- data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +3 -8
- data/lib/mongo/monitoring/event/server_opening.rb +1 -4
- data/lib/mongo/monitoring/event/topology_changed.rb +2 -5
- data/lib/mongo/monitoring/event/topology_closed.rb +1 -4
- data/lib/mongo/monitoring/event/topology_opening.rb +1 -4
- data/lib/mongo/monitoring/event.rb +0 -1
- data/lib/mongo/monitoring/publishable.rb +20 -30
- data/lib/mongo/monitoring/sdam_log_subscriber.rb +0 -2
- data/lib/mongo/monitoring/server_closed_log_subscriber.rb +0 -3
- data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +0 -3
- data/lib/mongo/monitoring/server_opening_log_subscriber.rb +0 -3
- data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +5 -8
- data/lib/mongo/monitoring/topology_closed_log_subscriber.rb +0 -3
- data/lib/mongo/monitoring/topology_opening_log_subscriber.rb +0 -3
- data/lib/mongo/monitoring/unified_sdam_log_subscriber.rb +1 -3
- data/lib/mongo/monitoring.rb +38 -39
- data/lib/mongo/operation/aggregate/op_msg.rb +0 -2
- data/lib/mongo/operation/aggregate/result.rb +3 -6
- data/lib/mongo/operation/aggregate.rb +0 -2
- data/lib/mongo/operation/collections_info/result.rb +0 -3
- data/lib/mongo/operation/collections_info.rb +0 -2
- data/lib/mongo/operation/command/op_msg.rb +1 -4
- data/lib/mongo/operation/command.rb +0 -2
- data/lib/mongo/operation/context.rb +13 -16
- data/lib/mongo/operation/count/op_msg.rb +2 -4
- data/lib/mongo/operation/count.rb +0 -2
- data/lib/mongo/operation/create/op_msg.rb +2 -5
- data/lib/mongo/operation/create.rb +4 -2
- data/lib/mongo/operation/create_index/op_msg.rb +3 -7
- data/lib/mongo/operation/create_index.rb +0 -2
- data/lib/mongo/operation/create_user/op_msg.rb +2 -4
- data/lib/mongo/operation/create_user.rb +0 -2
- data/lib/mongo/operation/delete/bulk_result.rb +2 -3
- data/lib/mongo/operation/delete/op_msg.rb +3 -10
- data/lib/mongo/operation/delete/result.rb +0 -3
- data/lib/mongo/operation/delete.rb +1 -5
- data/lib/mongo/operation/distinct/op_msg.rb +2 -5
- data/lib/mongo/operation/distinct.rb +0 -2
- data/lib/mongo/operation/drop/op_msg.rb +0 -2
- data/lib/mongo/operation/drop.rb +0 -2
- data/lib/mongo/operation/drop_database/op_msg.rb +0 -2
- data/lib/mongo/operation/drop_database.rb +0 -2
- data/lib/mongo/operation/drop_index/op_msg.rb +4 -6
- data/lib/mongo/operation/drop_index.rb +0 -2
- data/lib/mongo/operation/explain/op_msg.rb +0 -2
- data/lib/mongo/operation/explain/result.rb +0 -3
- data/lib/mongo/operation/explain.rb +0 -2
- data/lib/mongo/operation/find/builder/command.rb +4 -12
- data/lib/mongo/operation/find/builder/flags.rb +9 -15
- data/lib/mongo/operation/find/builder/modifiers.rb +1 -4
- data/lib/mongo/operation/find/builder.rb +0 -1
- data/lib/mongo/operation/find/op_msg.rb +4 -12
- data/lib/mongo/operation/find/result.rb +0 -3
- data/lib/mongo/operation/find.rb +0 -2
- data/lib/mongo/operation/get_more/command_builder.rb +1 -6
- data/lib/mongo/operation/get_more/op_msg.rb +10 -4
- data/lib/mongo/operation/get_more/result.rb +0 -3
- data/lib/mongo/operation/get_more.rb +0 -2
- data/lib/mongo/operation/indexes/op_msg.rb +0 -2
- data/lib/mongo/operation/indexes/result.rb +1 -5
- data/lib/mongo/operation/indexes.rb +0 -2
- data/lib/mongo/operation/insert/bulk_result.rb +2 -6
- data/lib/mongo/operation/insert/op_msg.rb +7 -6
- data/lib/mongo/operation/insert/result.rb +0 -3
- data/lib/mongo/operation/insert.rb +2 -5
- data/lib/mongo/operation/kill_cursors/command_builder.rb +0 -3
- data/lib/mongo/operation/kill_cursors/op_msg.rb +1 -3
- data/lib/mongo/operation/kill_cursors.rb +0 -2
- data/lib/mongo/operation/list_collections/op_msg.rb +4 -6
- data/lib/mongo/operation/list_collections/result.rb +1 -4
- data/lib/mongo/operation/list_collections.rb +0 -2
- data/lib/mongo/operation/map_reduce/op_msg.rb +0 -2
- data/lib/mongo/operation/map_reduce/result.rb +3 -6
- data/lib/mongo/operation/map_reduce.rb +0 -2
- data/lib/mongo/operation/op_msg_base.rb +0 -1
- data/lib/mongo/operation/parallel_scan/op_msg.rb +4 -5
- data/lib/mongo/operation/parallel_scan/result.rb +2 -5
- data/lib/mongo/operation/parallel_scan.rb +0 -2
- data/lib/mongo/operation/remove_user/op_msg.rb +2 -4
- data/lib/mongo/operation/remove_user.rb +0 -2
- data/lib/mongo/operation/result.rb +38 -48
- data/lib/mongo/operation/shared/bypass_document_validation.rb +3 -7
- data/lib/mongo/operation/shared/causal_consistency_supported.rb +0 -3
- data/lib/mongo/operation/shared/executable.rb +29 -31
- data/lib/mongo/operation/shared/executable_no_validate.rb +0 -3
- data/lib/mongo/operation/shared/executable_transaction_label.rb +0 -2
- data/lib/mongo/operation/shared/idable.rb +3 -6
- data/lib/mongo/operation/shared/limited.rb +0 -3
- data/lib/mongo/operation/shared/object_id_generator.rb +0 -3
- data/lib/mongo/operation/shared/op_msg_executable.rb +0 -2
- data/lib/mongo/operation/shared/polymorphic_lookup.rb +0 -2
- data/lib/mongo/operation/shared/polymorphic_result.rb +2 -4
- data/lib/mongo/operation/shared/read_preference_supported.rb +10 -15
- data/lib/mongo/operation/shared/response_handling.rb +13 -26
- data/lib/mongo/operation/shared/result/aggregatable.rb +12 -13
- data/lib/mongo/operation/shared/sessions_supported.rb +87 -99
- data/lib/mongo/operation/shared/specifiable.rb +37 -59
- data/lib/mongo/operation/shared/write.rb +12 -17
- data/lib/mongo/operation/shared/write_concern_supported.rb +4 -7
- data/lib/mongo/operation/update/bulk_result.rb +13 -17
- data/lib/mongo/operation/update/op_msg.rb +2 -5
- data/lib/mongo/operation/update/result.rb +5 -5
- data/lib/mongo/operation/update.rb +1 -5
- data/lib/mongo/operation/update_user/op_msg.rb +2 -4
- data/lib/mongo/operation/update_user.rb +0 -2
- data/lib/mongo/operation/users_info/op_msg.rb +2 -4
- data/lib/mongo/operation/users_info/result.rb +1 -4
- data/lib/mongo/operation/users_info.rb +0 -2
- data/lib/mongo/operation/write_command/op_msg.rb +2 -10
- data/lib/mongo/operation/write_command.rb +0 -2
- data/lib/mongo/operation.rb +9 -14
- data/lib/mongo/options/mapper.rb +8 -15
- data/lib/mongo/options/redacted.rb +7 -9
- data/lib/mongo/options.rb +0 -1
- data/lib/mongo/protocol/bit_vector.rb +3 -5
- data/lib/mongo/protocol/caching_hash.rb +2 -7
- data/lib/mongo/protocol/compressed.rb +5 -10
- data/lib/mongo/protocol/get_more.rb +2 -8
- data/lib/mongo/protocol/kill_cursors.rb +2 -8
- data/lib/mongo/protocol/message.rb +103 -105
- data/lib/mongo/protocol/msg.rb +48 -63
- data/lib/mongo/protocol/query.rb +32 -41
- data/lib/mongo/protocol/registry.rb +2 -5
- data/lib/mongo/protocol/reply.rb +10 -16
- data/lib/mongo/protocol/serializers.rb +41 -59
- data/lib/mongo/protocol.rb +0 -1
- data/lib/mongo/query_cache.rb +7 -15
- data/lib/mongo/retryable/backpressure.rb +31 -0
- data/lib/mongo/retryable/base_worker.rb +39 -13
- data/lib/mongo/retryable/read_worker.rb +77 -21
- data/lib/mongo/retryable/retry_policy.rb +59 -0
- data/lib/mongo/retryable/write_worker.rb +155 -56
- data/lib/mongo/retryable.rb +70 -9
- data/lib/mongo/search_index/view.rb +30 -10
- data/lib/mongo/semaphore.rb +0 -1
- data/lib/mongo/server/app_metadata/environment.rb +3 -3
- data/lib/mongo/server/app_metadata/platform.rb +17 -4
- data/lib/mongo/server/app_metadata.rb +4 -5
- data/lib/mongo/server/connection.rb +79 -61
- data/lib/mongo/server/connection_base.rb +43 -53
- data/lib/mongo/server/connection_common.rb +41 -64
- data/lib/mongo/server/connection_pool/generation_manager.rb +6 -11
- data/lib/mongo/server/connection_pool/populator.rb +1 -4
- data/lib/mongo/server/connection_pool.rb +195 -167
- data/lib/mongo/server/description/features.rb +51 -59
- data/lib/mongo/server/description/load_balancer.rb +0 -2
- data/lib/mongo/server/description.rb +117 -138
- data/lib/mongo/server/monitor/app_metadata.rb +3 -4
- data/lib/mongo/server/monitor/connection.rb +28 -35
- data/lib/mongo/server/monitor.rb +65 -60
- data/lib/mongo/server/pending_connection.rb +70 -71
- data/lib/mongo/server/push_monitor/connection.rb +0 -3
- data/lib/mongo/server/push_monitor.rb +21 -29
- data/lib/mongo/server/round_trip_time_calculator.rb +11 -17
- data/lib/mongo/server.rb +62 -94
- data/lib/mongo/server_selector/base.rb +133 -157
- data/lib/mongo/server_selector/nearest.rb +2 -5
- data/lib/mongo/server_selector/primary.rb +1 -5
- data/lib/mongo/server_selector/primary_preferred.rb +2 -6
- data/lib/mongo/server_selector/secondary.rb +2 -6
- data/lib/mongo/server_selector/secondary_preferred.rb +1 -5
- data/lib/mongo/server_selector.rb +3 -4
- data/lib/mongo/session/server_session.rb +6 -7
- data/lib/mongo/session/session_pool.rb +20 -34
- data/lib/mongo/session.rb +334 -199
- data/lib/mongo/socket/ocsp_cache.rb +8 -13
- data/lib/mongo/socket/ocsp_verifier.rb +69 -70
- data/lib/mongo/socket/ssl.rb +44 -43
- data/lib/mongo/socket/tcp.rb +5 -8
- data/lib/mongo/socket/unix.rb +0 -4
- data/lib/mongo/socket.rb +80 -102
- data/lib/mongo/srv/monitor.rb +10 -11
- data/lib/mongo/srv/resolver.rb +15 -24
- data/lib/mongo/srv/result.rb +25 -21
- data/lib/mongo/srv.rb +0 -1
- data/lib/mongo/timeout.rb +4 -11
- data/lib/mongo/topology_version.rb +8 -13
- data/lib/mongo/tracing/open_telemetry/command_tracer.rb +320 -0
- data/lib/mongo/tracing/open_telemetry/operation_tracer.rb +227 -0
- data/lib/mongo/tracing/open_telemetry/tracer.rb +236 -0
- data/lib/mongo/{error/server_api_not_supported.rb → tracing/open_telemetry.rb} +10 -10
- data/lib/mongo/tracing.rb +42 -0
- data/lib/mongo/uri/options_mapper.rb +135 -126
- data/lib/mongo/uri/srv_protocol.rb +34 -42
- data/lib/mongo/uri.rb +95 -139
- data/lib/mongo/utils.rb +5 -12
- data/lib/mongo/version.rb +1 -1
- data/lib/mongo/write_concern/acknowledged.rb +0 -2
- data/lib/mongo/write_concern/base.rb +6 -6
- data/lib/mongo/write_concern/unacknowledged.rb +0 -2
- data/lib/mongo/write_concern.rb +14 -15
- data/lib/mongo.rb +4 -3
- data/mongo.gemspec +17 -17
- metadata +11 -5
- data/lib/mongo/operation/shared/result/use_legacy_error_parser.rb +0 -32
- data/lib/mongo/operation/shared/validatable.rb +0 -87
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
# rubocop:todo all
|
|
3
2
|
|
|
4
3
|
# Copyright (C) 2015-2023 MongoDB Inc.
|
|
5
4
|
#
|
|
@@ -19,7 +18,6 @@ require 'mongo/retryable/base_worker'
|
|
|
19
18
|
|
|
20
19
|
module Mongo
|
|
21
20
|
module Retryable
|
|
22
|
-
|
|
23
21
|
# Implements the logic around retrying write operations.
|
|
24
22
|
#
|
|
25
23
|
# @api private
|
|
@@ -62,7 +60,7 @@ module Mongo
|
|
|
62
60
|
# @return [ Result ] The result of the operation.
|
|
63
61
|
#
|
|
64
62
|
# @since 2.1.0
|
|
65
|
-
def write_with_retry(write_concern, ending_transaction: false,
|
|
63
|
+
def write_with_retry(write_concern, context:, ending_transaction: false, &block)
|
|
66
64
|
session = context.session
|
|
67
65
|
|
|
68
66
|
ensure_valid_state!(ending_transaction, session)
|
|
@@ -104,19 +102,46 @@ module Mongo
|
|
|
104
102
|
# write should be sent.
|
|
105
103
|
# @yieldparam [ nil ] txn_num nil as transaction number.
|
|
106
104
|
# @yieldparam [ Operation::Context ] context The operation context.
|
|
107
|
-
def nro_write_with_retry(
|
|
105
|
+
def nro_write_with_retry(_write_concern, context:, &block)
|
|
108
106
|
session = context.session
|
|
109
107
|
server = select_server(cluster, ServerSelector.primary, session)
|
|
110
108
|
options = session&.client&.options || {}
|
|
111
109
|
|
|
112
110
|
if options[:retry_writes]
|
|
111
|
+
error_count = 0
|
|
112
|
+
error_to_raise = nil
|
|
113
113
|
begin
|
|
114
114
|
server.with_connection(connection_global_id: context.connection_global_id) do |connection|
|
|
115
115
|
yield connection, nil, context
|
|
116
116
|
end
|
|
117
|
+
rescue Error::TimeoutError
|
|
118
|
+
raise
|
|
117
119
|
rescue *retryable_exceptions, Error::PoolError, Error::OperationFailure::Family => e
|
|
118
|
-
e
|
|
119
|
-
|
|
120
|
+
if retryable_overload_error?(e)
|
|
121
|
+
error_count += 1
|
|
122
|
+
error_to_raise ||= e
|
|
123
|
+
unless e.respond_to?(:label?) && e.label?('NoWritesPerformed')
|
|
124
|
+
error_to_raise = e
|
|
125
|
+
end
|
|
126
|
+
delay = retry_policy.backoff_delay(error_count)
|
|
127
|
+
raise error_to_raise unless retry_policy.should_retry_overload?(error_count, delay, context: context)
|
|
128
|
+
|
|
129
|
+
log_retry(e, message: 'Write retry (overload backoff)')
|
|
130
|
+
sleep(delay)
|
|
131
|
+
begin
|
|
132
|
+
server = select_server(
|
|
133
|
+
cluster, ServerSelector.primary, session, server,
|
|
134
|
+
error: e, timeout: context.remaining_timeout_sec
|
|
135
|
+
)
|
|
136
|
+
rescue Error, Error::AuthError => select_err
|
|
137
|
+
error_to_raise.add_note("later retry failed: #{select_err.class}: #{select_err}")
|
|
138
|
+
raise error_to_raise
|
|
139
|
+
end
|
|
140
|
+
retry
|
|
141
|
+
else
|
|
142
|
+
e.add_note('retries disabled')
|
|
143
|
+
raise e
|
|
144
|
+
end
|
|
120
145
|
end
|
|
121
146
|
else
|
|
122
147
|
legacy_write_with_retry(server, context: context, &block)
|
|
@@ -134,11 +159,7 @@ module Mongo
|
|
|
134
159
|
def retry_write_allowed?(session, write_concern)
|
|
135
160
|
return false unless session&.retry_writes?
|
|
136
161
|
|
|
137
|
-
|
|
138
|
-
true
|
|
139
|
-
else
|
|
140
|
-
WriteConcern.get(write_concern).acknowledged?
|
|
141
|
-
end
|
|
162
|
+
write_concern.nil? || WriteConcern.get(write_concern).acknowledged?
|
|
142
163
|
end
|
|
143
164
|
|
|
144
165
|
private
|
|
@@ -150,9 +171,9 @@ module Mongo
|
|
|
150
171
|
# @param [ nil | Mongo::Session ] session The session that the operation
|
|
151
172
|
# is being run on (if any).
|
|
152
173
|
def ensure_valid_state!(ending_transaction, session)
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
end
|
|
174
|
+
return unless ending_transaction && !session
|
|
175
|
+
|
|
176
|
+
raise ArgumentError, 'Cannot end a transaction without a session'
|
|
156
177
|
end
|
|
157
178
|
|
|
158
179
|
# Implements legacy write retrying functionality by yielding to the passed
|
|
@@ -199,16 +220,13 @@ module Mongo
|
|
|
199
220
|
e.add_note('legacy retry')
|
|
200
221
|
e.add_note("attempt #{attempt}")
|
|
201
222
|
server = nil
|
|
202
|
-
if attempt > client.max_write_retries
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
else
|
|
210
|
-
raise e
|
|
211
|
-
end
|
|
223
|
+
raise e if attempt > client.max_write_retries
|
|
224
|
+
|
|
225
|
+
raise e unless e.label?('RetryableWriteError')
|
|
226
|
+
|
|
227
|
+
log_retry(e, message: 'Legacy write retry')
|
|
228
|
+
cluster.scan!(false)
|
|
229
|
+
retry
|
|
212
230
|
end
|
|
213
231
|
end
|
|
214
232
|
|
|
@@ -232,6 +250,7 @@ module Mongo
|
|
|
232
250
|
def modern_write_with_retry(session, server, context, &block)
|
|
233
251
|
txn_num = nil
|
|
234
252
|
connection_succeeded = false
|
|
253
|
+
was_starting = false
|
|
235
254
|
|
|
236
255
|
server.with_connection(
|
|
237
256
|
connection_global_id: context.connection_global_id,
|
|
@@ -241,6 +260,7 @@ module Mongo
|
|
|
241
260
|
|
|
242
261
|
session.materialize_if_needed
|
|
243
262
|
txn_num = session.in_transaction? ? session.txn_num : session.next_txn_num
|
|
263
|
+
was_starting = session.starting_transaction?
|
|
244
264
|
|
|
245
265
|
# The context needs to be duplicated here because we will be using
|
|
246
266
|
# it later for the retry as well.
|
|
@@ -249,15 +269,28 @@ module Mongo
|
|
|
249
269
|
rescue *retryable_exceptions, Error::PoolError, Auth::Unauthorized, Error::OperationFailure::Family => e
|
|
250
270
|
e.add_notes('modern retry', 'attempt 1')
|
|
251
271
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
272
|
+
is_overload = retryable_overload_error?(e)
|
|
273
|
+
unless is_overload
|
|
274
|
+
if e.is_a?(Error::OperationFailure::Family)
|
|
275
|
+
ensure_retryable!(e)
|
|
276
|
+
else
|
|
277
|
+
ensure_labeled_retryable!(e, connection_succeeded, session)
|
|
278
|
+
end
|
|
256
279
|
end
|
|
257
280
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
281
|
+
retry_context = context.with(is_retry: true)
|
|
282
|
+
|
|
283
|
+
if is_overload
|
|
284
|
+
overload_write_retry(e, session, txn_num,
|
|
285
|
+
context: retry_context.with(overload_only_retry: true),
|
|
286
|
+
failed_server: server, error_count: 1,
|
|
287
|
+
was_starting_transaction: was_starting,
|
|
288
|
+
&block)
|
|
289
|
+
else
|
|
290
|
+
# Context#with creates a new context, which is not necessary here
|
|
291
|
+
# but the API is less prone to misuse this way.
|
|
292
|
+
retry_write(e, txn_num, context: retry_context, failed_server: server, &block)
|
|
293
|
+
end
|
|
261
294
|
end
|
|
262
295
|
|
|
263
296
|
# Called after a failed write, this will retry the write no more than
|
|
@@ -272,6 +305,7 @@ module Mongo
|
|
|
272
305
|
#
|
|
273
306
|
# @return [ Result ] The result of the operation.
|
|
274
307
|
def retry_write(original_error, txn_num, context:, failed_server: nil, &block)
|
|
308
|
+
failed_error ||= original_error
|
|
275
309
|
context&.check_timeout!
|
|
276
310
|
|
|
277
311
|
session = context.session
|
|
@@ -286,6 +320,7 @@ module Mongo
|
|
|
286
320
|
ServerSelector.primary,
|
|
287
321
|
session,
|
|
288
322
|
failed_server,
|
|
323
|
+
error: failed_error,
|
|
289
324
|
timeout: context.remaining_timeout_sec
|
|
290
325
|
)
|
|
291
326
|
|
|
@@ -296,7 +331,7 @@ module Mongo
|
|
|
296
331
|
|
|
297
332
|
# When we want to raise the original error, we must not run the
|
|
298
333
|
# rescue blocks below that add diagnostics because the diagnostics
|
|
299
|
-
# added would either be
|
|
334
|
+
# added would either be redundant (e.g. modern retry note) or wrong
|
|
300
335
|
# (e.g. "attempt 2", we are raising the exception produced in the
|
|
301
336
|
# first attempt and haven't attempted the second time). Use the
|
|
302
337
|
# special marker class to bypass the ordinarily applicable rescues.
|
|
@@ -309,12 +344,24 @@ module Mongo
|
|
|
309
344
|
yield(connection, txn_num, context)
|
|
310
345
|
end
|
|
311
346
|
rescue *retryable_exceptions, Error::PoolError => e
|
|
347
|
+
if retryable_overload_error?(e)
|
|
348
|
+
e.add_notes('modern retry', "attempt #{attempt}")
|
|
349
|
+
return overload_write_retry(e, context.session, txn_num,
|
|
350
|
+
context: context, failed_server: server, error_count: attempt, was_starting_transaction: false, &block)
|
|
351
|
+
end
|
|
312
352
|
maybe_fail_on_retryable(e, original_error, context, attempt)
|
|
313
353
|
failed_server = server
|
|
354
|
+
failed_error = e
|
|
314
355
|
retry
|
|
315
356
|
rescue Error::OperationFailure::Family => e
|
|
357
|
+
if retryable_overload_error?(e)
|
|
358
|
+
e.add_notes('modern retry', "attempt #{attempt}")
|
|
359
|
+
return overload_write_retry(e, context.session, txn_num,
|
|
360
|
+
context: context, failed_server: server, error_count: attempt, was_starting_transaction: false, &block)
|
|
361
|
+
end
|
|
316
362
|
maybe_fail_on_operation_failure(e, original_error, context, attempt)
|
|
317
363
|
failed_server = server
|
|
364
|
+
failed_error = e
|
|
318
365
|
retry
|
|
319
366
|
rescue Mongo::Error::TimeoutError
|
|
320
367
|
raise
|
|
@@ -324,41 +371,93 @@ module Mongo
|
|
|
324
371
|
raise original_error
|
|
325
372
|
end
|
|
326
373
|
|
|
327
|
-
# Retry
|
|
328
|
-
#
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
374
|
+
# Retry loop for overload write errors with exponential backoff.
|
|
375
|
+
#
|
|
376
|
+
# Per the client-backpressure spec, backoff is applied if and only
|
|
377
|
+
# if the error triggering the retry is an overload error. Non-overload
|
|
378
|
+
# retryable errors that occur within this loop are retried immediately
|
|
379
|
+
# (without backoff) but still count toward MAX_RETRIES.
|
|
380
|
+
def overload_write_retry(last_error, session, txn_num, context:, failed_server:, error_count:,
|
|
381
|
+
was_starting_transaction: false)
|
|
382
|
+
# Track the error to return per the NoWritesPerformed spec rules:
|
|
383
|
+
# - first error is always saved
|
|
384
|
+
# - only update when a new error does NOT have NoWritesPerformed
|
|
385
|
+
error_to_raise = last_error
|
|
386
|
+
last_was_overload = true
|
|
387
|
+
|
|
388
|
+
loop do
|
|
389
|
+
delay = last_was_overload ? retry_policy.backoff_delay(error_count) : 0
|
|
390
|
+
raise error_to_raise unless retry_policy.should_retry_overload?(error_count, delay, context: context)
|
|
391
|
+
|
|
392
|
+
log_retry(last_error, message: 'Write retry (overload backoff)')
|
|
393
|
+
sleep(delay) if last_was_overload
|
|
394
|
+
|
|
395
|
+
begin
|
|
396
|
+
server = select_server(
|
|
397
|
+
cluster, ServerSelector.primary, session, failed_server,
|
|
398
|
+
error: last_error,
|
|
399
|
+
timeout: context.remaining_timeout_sec
|
|
400
|
+
)
|
|
401
|
+
rescue Error, Error::AuthError => e
|
|
402
|
+
error_to_raise.add_note("later retry failed: #{e.class}: #{e}")
|
|
403
|
+
raise error_to_raise
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
unless server.retry_writes?
|
|
407
|
+
error_to_raise.add_note('did not retry because server does not support retryable writes')
|
|
408
|
+
raise error_to_raise
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
begin
|
|
412
|
+
session.revert_to_starting_transaction! if was_starting_transaction
|
|
413
|
+
context.check_timeout!
|
|
414
|
+
result = server.with_connection(connection_global_id: context.connection_global_id) do |connection|
|
|
415
|
+
yield connection, txn_num, context
|
|
416
|
+
end
|
|
417
|
+
return result
|
|
418
|
+
rescue Error::TimeoutError
|
|
419
|
+
raise
|
|
420
|
+
rescue *retryable_exceptions, Error::PoolError, Error::OperationFailure::Family => e
|
|
421
|
+
error_count += 1
|
|
422
|
+
e.add_notes('modern retry', "attempt #{error_count}")
|
|
423
|
+
is_overload = retryable_overload_error?(e)
|
|
424
|
+
if e.is_a?(Error::OperationFailure::Family)
|
|
425
|
+
raise e unless is_overload || (e.label?('RetryableWriteError') && !e.label?('NoWritesPerformed'))
|
|
426
|
+
else
|
|
427
|
+
raise e unless is_overload || e.write_retryable?
|
|
428
|
+
end
|
|
429
|
+
unless e.respond_to?(:label?) && e.label?('NoWritesPerformed')
|
|
430
|
+
error_to_raise = e
|
|
431
|
+
end
|
|
432
|
+
last_was_overload = is_overload
|
|
433
|
+
context = context.with(overload_only_retry: false) unless is_overload
|
|
434
|
+
failed_server = server
|
|
435
|
+
last_error = e
|
|
436
|
+
rescue Error, Error::AuthError => e
|
|
437
|
+
error_to_raise.add_note("later retry failed: #{e.class}: #{e}")
|
|
438
|
+
raise error_to_raise
|
|
439
|
+
end
|
|
440
|
+
end
|
|
335
441
|
end
|
|
336
442
|
|
|
337
443
|
# Make sure the exception object is labeled 'RetryableWriteError'. If it
|
|
338
444
|
# isn't, and should not be, re-raise the exception.
|
|
339
445
|
def ensure_labeled_retryable!(e, connection_succeeded, session)
|
|
340
|
-
if
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
raise e
|
|
349
|
-
end
|
|
350
|
-
end
|
|
446
|
+
return if e.label?('RetryableWriteError')
|
|
447
|
+
# If there was an error before the connection was successfully
|
|
448
|
+
# checked out and connected, there was no connection present to use
|
|
449
|
+
# for adding labels. Therefore, we should check if it is retryable,
|
|
450
|
+
# and if it is, add the label and retry it.
|
|
451
|
+
raise e unless !connection_succeeded && !session.in_transaction? && e.write_retryable?
|
|
452
|
+
|
|
453
|
+
e.add_label('RetryableWriteError')
|
|
351
454
|
end
|
|
352
455
|
|
|
353
456
|
# Make sure the exception object supports retryable writes. If it does,
|
|
354
457
|
# make sure it has been appropriately labeled. If either condition fails,
|
|
355
458
|
# raise an exception.
|
|
356
459
|
def ensure_retryable!(e)
|
|
357
|
-
|
|
358
|
-
raise_unsupported_error(e)
|
|
359
|
-
elsif !e.label?('RetryableWriteError')
|
|
360
|
-
raise e
|
|
361
|
-
end
|
|
460
|
+
raise e unless e.label?('RetryableWriteError')
|
|
362
461
|
end
|
|
363
462
|
|
|
364
463
|
# Raise either e, or original_error, depending on whether e is
|
data/lib/mongo/retryable.rb
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
# rubocop:todo all
|
|
3
2
|
|
|
4
3
|
# Copyright (C) 2015-2020 MongoDB Inc.
|
|
5
4
|
#
|
|
@@ -15,11 +14,12 @@
|
|
|
15
14
|
# See the License for the specific language governing permissions and
|
|
16
15
|
# limitations under the License.
|
|
17
16
|
|
|
17
|
+
require 'mongo/retryable/backpressure'
|
|
18
|
+
require 'mongo/retryable/retry_policy'
|
|
18
19
|
require 'mongo/retryable/read_worker'
|
|
19
20
|
require 'mongo/retryable/write_worker'
|
|
20
21
|
|
|
21
22
|
module Mongo
|
|
22
|
-
|
|
23
23
|
# Defines basic behavior around retrying operations.
|
|
24
24
|
#
|
|
25
25
|
# @since 2.1.0
|
|
@@ -28,14 +28,14 @@ module Mongo
|
|
|
28
28
|
|
|
29
29
|
# Delegate the public read_with_retry methods to the read_worker
|
|
30
30
|
def_delegators :read_worker,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
:read_with_retry_cursor,
|
|
32
|
+
:read_with_retry,
|
|
33
|
+
:read_with_one_retry
|
|
34
34
|
|
|
35
35
|
# Delegate the public write_with_retry methods to the write_worker
|
|
36
36
|
def_delegators :write_worker,
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
:write_with_retry,
|
|
38
|
+
:nro_write_with_retry
|
|
39
39
|
|
|
40
40
|
# This is a separate method to make it possible for the test suite to
|
|
41
41
|
# assert that server selection is performed during retry attempts.
|
|
@@ -46,16 +46,37 @@ module Mongo
|
|
|
46
46
|
# @api private
|
|
47
47
|
#
|
|
48
48
|
# @return [ Mongo::Server ] A server matching the server preference.
|
|
49
|
-
def select_server(cluster, server_selector, session, failed_server = nil, timeout: nil)
|
|
49
|
+
def select_server(cluster, server_selector, session, failed_server = nil, error: nil, timeout: nil)
|
|
50
|
+
deprioritized = if failed_server && deprioritize_server?(cluster, error)
|
|
51
|
+
[ failed_server ]
|
|
52
|
+
else
|
|
53
|
+
[]
|
|
54
|
+
end
|
|
50
55
|
server_selector.select_server(
|
|
51
56
|
cluster,
|
|
52
57
|
nil,
|
|
53
58
|
session,
|
|
54
|
-
deprioritized:
|
|
59
|
+
deprioritized: deprioritized,
|
|
55
60
|
timeout: timeout
|
|
56
61
|
)
|
|
57
62
|
end
|
|
58
63
|
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
# Whether the failed server should be deprioritized during server
|
|
67
|
+
# selection for a retry attempt. For sharded and load-balanced
|
|
68
|
+
# topologies, servers are always deprioritized on any retryable error.
|
|
69
|
+
# For replica sets, servers are deprioritized on overload errors only
|
|
70
|
+
# when enableOverloadRetargeting is enabled.
|
|
71
|
+
def deprioritize_server?(cluster, error)
|
|
72
|
+
return true if cluster.sharded? || cluster.load_balanced?
|
|
73
|
+
return false unless client.options[:enable_overload_retargeting]
|
|
74
|
+
|
|
75
|
+
error.respond_to?(:label?) && error.label?('SystemOverloadedError')
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
public
|
|
79
|
+
|
|
59
80
|
# Returns the read worker for handling retryable reads.
|
|
60
81
|
#
|
|
61
82
|
# @api private
|
|
@@ -75,5 +96,45 @@ module Mongo
|
|
|
75
96
|
def write_worker
|
|
76
97
|
@write_worker ||= WriteWorker.new(self)
|
|
77
98
|
end
|
|
99
|
+
|
|
100
|
+
# Wraps an operation with overload retry logic. On overload errors
|
|
101
|
+
# (SystemOverloadedError + RetryableError), retries the block with
|
|
102
|
+
# exponential backoff up to MAX_RETRIES times.
|
|
103
|
+
#
|
|
104
|
+
# The block should include server selection so it is re-done on retry.
|
|
105
|
+
# For cursor operations (getMore), the same server is reused since the
|
|
106
|
+
# cursor is pinned.
|
|
107
|
+
#
|
|
108
|
+
# @param [ Operation::Context | nil ] context The operation context
|
|
109
|
+
# for CSOT deadline checking.
|
|
110
|
+
# @param [ true | false ] retry_enabled Whether overload retries are
|
|
111
|
+
# permitted. When false, overload errors are raised immediately
|
|
112
|
+
# without retrying (used when retryReads/retryWrites is disabled).
|
|
113
|
+
#
|
|
114
|
+
# @return [ Object ] The result of the block.
|
|
115
|
+
#
|
|
116
|
+
# @api private
|
|
117
|
+
def with_overload_retry(context: nil, retry_enabled: true)
|
|
118
|
+
return yield unless retry_enabled
|
|
119
|
+
|
|
120
|
+
error_count = 0
|
|
121
|
+
loop do
|
|
122
|
+
result = yield
|
|
123
|
+
|
|
124
|
+
return result
|
|
125
|
+
rescue Error::TimeoutError
|
|
126
|
+
raise
|
|
127
|
+
rescue Error::OperationFailure::Family => e
|
|
128
|
+
raise e unless e.label?('SystemOverloadedError') && e.label?('RetryableError')
|
|
129
|
+
|
|
130
|
+
error_count += 1
|
|
131
|
+
policy = client.retry_policy
|
|
132
|
+
delay = policy.backoff_delay(error_count)
|
|
133
|
+
raise e unless policy.should_retry_overload?(error_count, delay, context: context)
|
|
134
|
+
|
|
135
|
+
Logger.logger.warn("Overload retry due to: #{e.class.name}: #{e.message}")
|
|
136
|
+
sleep(delay)
|
|
137
|
+
end
|
|
138
|
+
end
|
|
78
139
|
end
|
|
79
140
|
end
|
|
@@ -4,6 +4,7 @@ module Mongo
|
|
|
4
4
|
module SearchIndex
|
|
5
5
|
# A class representing a view of search indexes.
|
|
6
6
|
class View
|
|
7
|
+
extend Forwardable
|
|
7
8
|
include Enumerable
|
|
8
9
|
include Retryable
|
|
9
10
|
include Collection::Helpers
|
|
@@ -21,6 +22,8 @@ module Mongo
|
|
|
21
22
|
# when querying the available indexes.
|
|
22
23
|
attr_reader :aggregate_options
|
|
23
24
|
|
|
25
|
+
def_delegators :@collection, :tracer
|
|
26
|
+
|
|
24
27
|
# Create the new search index view.
|
|
25
28
|
#
|
|
26
29
|
# @param [ Collection ] collection The collection.
|
|
@@ -46,23 +49,33 @@ module Mongo
|
|
|
46
49
|
#
|
|
47
50
|
# @param [ Hash ] definition The definition of the search index.
|
|
48
51
|
# @param [ nil | String ] name The name to give the new search index.
|
|
52
|
+
# @param [ String ] type The type of the search index. Possible values
|
|
53
|
+
# are 'search' and 'vectorSearch'. The default is 'search'.
|
|
49
54
|
#
|
|
50
55
|
# @return [ String ] the name of the new search index.
|
|
51
56
|
def create_one(definition, name: nil, type: 'search')
|
|
52
|
-
|
|
57
|
+
spec = { definition: definition, type: type }.tap do |sp|
|
|
58
|
+
sp[:name] = name unless name.nil?
|
|
59
|
+
end
|
|
60
|
+
create_many([ spec ]).first
|
|
53
61
|
end
|
|
54
62
|
|
|
55
63
|
# Create multiple search indexes with a single command.
|
|
56
64
|
#
|
|
57
65
|
# @param [ Array<Hash> ] indexes The description of the indexes to
|
|
58
66
|
# create. Each element of the list must be a hash with a definition
|
|
59
|
-
# key, and an optional
|
|
67
|
+
# key, an optional name key, and an optional type key. The type key
|
|
68
|
+
# must be one of 'search' or 'vectorSearch'. The default is 'search'.
|
|
60
69
|
#
|
|
61
70
|
# @return [ Array<String> ] the names of the new search indexes.
|
|
62
71
|
def create_many(indexes)
|
|
63
72
|
spec = spec_with(indexes: indexes.map { |v| validate_search_index!(v) })
|
|
64
|
-
|
|
65
|
-
|
|
73
|
+
operation = Operation::CreateSearchIndexes.new(spec)
|
|
74
|
+
context = execution_context
|
|
75
|
+
tracer.trace_operation(operation, context, op_name: 'createSearchIndexes') do
|
|
76
|
+
result = operation.execute(next_primary, context: context)
|
|
77
|
+
result.first['indexesCreated'].map { |idx| idx['name'] }
|
|
78
|
+
end
|
|
66
79
|
end
|
|
67
80
|
|
|
68
81
|
# Drop the search index with the given id, or name. One or the other must
|
|
@@ -78,16 +91,19 @@ module Mongo
|
|
|
78
91
|
|
|
79
92
|
spec = spec_with(index_id: id, index_name: name)
|
|
80
93
|
op = Operation::DropSearchIndex.new(spec)
|
|
94
|
+
context = execution_context
|
|
81
95
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
96
|
+
tracer.trace_operation(op, context, op_name: 'dropSearchIndex') do
|
|
97
|
+
# per the spec:
|
|
98
|
+
# Drivers MUST suppress NamespaceNotFound errors for the
|
|
99
|
+
# ``dropSearchIndex`` helper. Drop operations should be idempotent.
|
|
100
|
+
do_drop(op, nil, context)
|
|
101
|
+
end
|
|
86
102
|
end
|
|
87
103
|
|
|
88
104
|
# Iterate over the search indexes.
|
|
89
105
|
#
|
|
90
|
-
# @param [ Proc ] block if given, each search index will be
|
|
106
|
+
# @param [ Proc ] block if given, each search index will be yielded to
|
|
91
107
|
# the block.
|
|
92
108
|
#
|
|
93
109
|
# @return [ self | Enumerator ] if a block is given, self is returned.
|
|
@@ -124,7 +140,11 @@ module Mongo
|
|
|
124
140
|
validate_id_or_name!(id, name)
|
|
125
141
|
|
|
126
142
|
spec = spec_with(index_id: id, index_name: name, index: definition)
|
|
127
|
-
Operation::UpdateSearchIndex.new(spec)
|
|
143
|
+
op = Operation::UpdateSearchIndex.new(spec)
|
|
144
|
+
context = execution_context
|
|
145
|
+
tracer.trace_operation(op, context, op_name: 'updateSearchIndex') do
|
|
146
|
+
op.execute(next_primary, context: context)
|
|
147
|
+
end
|
|
128
148
|
end
|
|
129
149
|
|
|
130
150
|
# The following methods are to make the view act more like an array,
|
data/lib/mongo/semaphore.rb
CHANGED
|
@@ -100,7 +100,7 @@ module Mongo
|
|
|
100
100
|
# @return [ String | nil ] the error message explaining why a valid
|
|
101
101
|
# FaaS environment was not detected, or nil if no error occurred.
|
|
102
102
|
#
|
|
103
|
-
# @note These error
|
|
103
|
+
# @note These error messages are not to be propagated to the
|
|
104
104
|
# user; they are intended only for troubleshooting and debugging.)
|
|
105
105
|
attr_reader :error
|
|
106
106
|
|
|
@@ -194,7 +194,7 @@ module Mongo
|
|
|
194
194
|
|
|
195
195
|
private
|
|
196
196
|
|
|
197
|
-
# Searches the
|
|
197
|
+
# Searches the DISCRIMINATORS list to see which (if any) apply to
|
|
198
198
|
# the current environment.
|
|
199
199
|
#
|
|
200
200
|
# @return [ String | nil ] the name of the detected FaaS provider.
|
|
@@ -248,7 +248,7 @@ module Mongo
|
|
|
248
248
|
end
|
|
249
249
|
|
|
250
250
|
# Determines whether the named environment variable exists, and (if
|
|
251
|
-
# a pattern has been declared for that
|
|
251
|
+
# a pattern has been declared for that discriminator) whether the
|
|
252
252
|
# pattern matches the value of the variable.
|
|
253
253
|
#
|
|
254
254
|
# @param [ String ] var the name of the environment variable
|
|
@@ -34,21 +34,34 @@ module Mongo
|
|
|
34
34
|
@metadata = metadata
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
# Queries whether the current runtime is Ruby MRI or not.
|
|
38
|
+
#
|
|
39
|
+
# @return [ true | false ] whether the runtime is Ruby MRI or not.
|
|
40
|
+
def mri?
|
|
41
|
+
RUBY_ENGINE == 'ruby'
|
|
42
|
+
end
|
|
43
|
+
|
|
37
44
|
# Queries whether the current runtime is JRuby or not.
|
|
38
45
|
#
|
|
39
46
|
# @return [ true | false ] whether the runtime is JRuby or not.
|
|
40
47
|
def jruby?
|
|
41
|
-
|
|
48
|
+
RUBY_ENGINE == 'jruby'
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
ENGINE_NAMES = { 'jruby' => 'JRuby', 'truffleruby' => 'TruffleRuby' }.freeze
|
|
52
|
+
|
|
53
|
+
def engine_name
|
|
54
|
+
ENGINE_NAMES[RUBY_ENGINE] || RUBY_ENGINE
|
|
42
55
|
end
|
|
43
56
|
|
|
44
57
|
# Returns the list of Ruby versions that identify this runtime.
|
|
45
58
|
#
|
|
46
59
|
# @return [ Array<String> ] the list of ruby versions
|
|
47
60
|
def ruby_versions
|
|
48
|
-
if
|
|
49
|
-
[ "JRuby #{JRUBY_VERSION}", "like Ruby #{RUBY_VERSION}" ]
|
|
50
|
-
else
|
|
61
|
+
if mri?
|
|
51
62
|
[ "Ruby #{RUBY_VERSION}" ]
|
|
63
|
+
else
|
|
64
|
+
[ "#{engine_name} #{RUBY_ENGINE_VERSION}", "like Ruby #{RUBY_VERSION}" ]
|
|
52
65
|
end
|
|
53
66
|
end
|
|
54
67
|
|
|
@@ -46,8 +46,7 @@ module Mongo
|
|
|
46
46
|
#
|
|
47
47
|
# @param [ Hash ] options Metadata options.
|
|
48
48
|
# @option options [ String, Symbol ] :app_name Application name that is
|
|
49
|
-
# printed to the mongod logs upon establishing a connection
|
|
50
|
-
# versions >= 3.4.
|
|
49
|
+
# printed to the mongod logs upon establishing a connection
|
|
51
50
|
# @option options [ Symbol ] :auth_mech The authentication mechanism to
|
|
52
51
|
# use. One of :mongodb_cr, :mongodb_x509, :plain, :scram, :scram256
|
|
53
52
|
# @option options [ String ] :auth_source The source to authenticate from.
|
|
@@ -57,7 +56,6 @@ module Mongo
|
|
|
57
56
|
# driver only supports 'zstd', 'snappy' and 'zlib'.
|
|
58
57
|
# @option options [ String ] :platform Platform information to include in
|
|
59
58
|
# the metadata printed to the mongod logs upon establishing a connection
|
|
60
|
-
# in server versions >= 3.4.
|
|
61
59
|
# @option options [ Symbol ] :purpose The purpose of this connection.
|
|
62
60
|
# @option options [ Hash ] :server_api The requested server API version.
|
|
63
61
|
# This hash can have the following items:
|
|
@@ -97,7 +95,7 @@ module Mongo
|
|
|
97
95
|
|
|
98
96
|
# @return [ Hash | nil ] The requested server API version.
|
|
99
97
|
#
|
|
100
|
-
#
|
|
98
|
+
# This hash can have the following items:
|
|
101
99
|
# - *:version* -- string
|
|
102
100
|
# - *:strict* -- boolean
|
|
103
101
|
# - *:deprecation_errors* -- boolean
|
|
@@ -132,6 +130,7 @@ module Mongo
|
|
|
132
130
|
doc[:driver] = driver_doc
|
|
133
131
|
doc[:os] = os_doc
|
|
134
132
|
doc[:platform] = platform_string
|
|
133
|
+
doc[:backpressure] = true
|
|
135
134
|
env_doc.tap { |env| doc[:env] = env if env }
|
|
136
135
|
end
|
|
137
136
|
end
|
|
@@ -139,7 +138,7 @@ module Mongo
|
|
|
139
138
|
private
|
|
140
139
|
|
|
141
140
|
# Check whether it is possible to build a valid app metadata document
|
|
142
|
-
# with params provided on
|
|
141
|
+
# with params provided on initialization.
|
|
143
142
|
#
|
|
144
143
|
# @raise [ Error::InvalidApplicationName ] When the metadata are invalid.
|
|
145
144
|
def validate!
|