mongo 2.23.0 → 2.24.1
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 +20 -17
- data/lib/mongo/bulk_write/result_combiner.rb +17 -13
- 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 +230 -275
- 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 +148 -183
- data/lib/mongo/cluster_time.rb +14 -31
- data/lib/mongo/collection/helpers.rb +5 -8
- data/lib/mongo/collection/view/aggregation.rb +5 -10
- 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 +35 -28
- data/lib/mongo/collection/view/map_reduce.rb +20 -25
- data/lib/mongo/collection/view/readable.rb +50 -57
- data/lib/mongo/collection/view/writable.rb +56 -72
- data/lib/mongo/collection/view.rb +9 -8
- data/lib/mongo/collection.rb +63 -76
- 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 +7 -4
- data/lib/mongo/crypt/auto_decryption_context.rb +0 -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 +149 -155
- data/lib/mongo/crypt/context.rb +10 -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 +0 -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 +16 -37
- data/lib/mongo/database.rb +52 -56
- data/lib/mongo/dbref.rb +0 -1
- 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 +35 -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 +10 -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 +62 -36
- 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 +49 -48
- 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 +2 -3
- data/lib/mongo/monitoring/server_opening_log_subscriber.rb +0 -3
- data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +8 -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 +0 -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 +2 -4
- 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 -47
- 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 +20 -29
- 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 +32 -58
- 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 +1 -1
- data/lib/mongo/semaphore.rb +0 -1
- data/lib/mongo/server/app_metadata/environment.rb +3 -3
- data/lib/mongo/server/app_metadata.rb +4 -5
- data/lib/mongo/server/connection.rb +61 -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 +250 -175
- data/lib/mongo/server/description/features.rb +23 -60
- data/lib/mongo/server/description/load_balancer.rb +0 -2
- data/lib/mongo/server/description.rb +138 -137
- 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 +60 -93
- data/lib/mongo/server_selector/base.rb +146 -157
- data/lib/mongo/server_selector/nearest.rb +5 -5
- data/lib/mongo/server_selector/primary.rb +4 -5
- data/lib/mongo/server_selector/primary_preferred.rb +5 -6
- data/lib/mongo/server_selector/secondary.rb +5 -6
- data/lib/mongo/server_selector/secondary_preferred.rb +4 -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 +321 -189
- 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 +6 -11
- data/lib/mongo/srv/resolver.rb +15 -24
- data/lib/mongo/srv/result.rb +18 -24
- 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 +28 -1
- data/lib/mongo/tracing/open_telemetry/operation_tracer.rb +1 -1
- data/lib/mongo/tracing/open_telemetry/tracer.rb +1 -1
- data/lib/mongo/uri/options_mapper.rb +135 -126
- data/lib/mongo/uri/srv_protocol.rb +25 -38
- 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 +2 -3
- data/mongo.gemspec +17 -17
- metadata +5 -5
- data/lib/mongo/error/server_api_not_supported.rb +0 -27
- 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) 2014-2020 MongoDB Inc.
|
|
5
4
|
#
|
|
@@ -17,7 +16,6 @@
|
|
|
17
16
|
|
|
18
17
|
module Mongo
|
|
19
18
|
class Server
|
|
20
|
-
|
|
21
19
|
# Represents a connection pool for server connections.
|
|
22
20
|
#
|
|
23
21
|
# @since 2.0.0, largely rewritten in 2.9.0
|
|
@@ -52,7 +50,7 @@ module Mongo
|
|
|
52
50
|
# thus anything over 15 seconds is potentially dangerous.
|
|
53
51
|
#
|
|
54
52
|
# @since 2.9.0
|
|
55
|
-
DEFAULT_WAIT_TIMEOUT = 10
|
|
53
|
+
DEFAULT_WAIT_TIMEOUT = 10
|
|
56
54
|
|
|
57
55
|
# Condition variable broadcast when the size of the pool changes
|
|
58
56
|
# to wake up the populator
|
|
@@ -100,31 +98,32 @@ module Mongo
|
|
|
100
98
|
# @since 2.0.0, API changed in 2.9.0
|
|
101
99
|
|
|
102
100
|
def initialize(server, options = {})
|
|
103
|
-
unless server.is_a?(Server)
|
|
104
|
-
|
|
105
|
-
end
|
|
101
|
+
raise ArgumentError, 'First argument must be a Server instance' unless server.is_a?(Server)
|
|
102
|
+
|
|
106
103
|
options = options.dup
|
|
107
104
|
if options[:min_size] && options[:min_pool_size] && options[:min_size] != options[:min_pool_size]
|
|
108
|
-
raise ArgumentError,
|
|
105
|
+
raise ArgumentError,
|
|
106
|
+
"Min size #{options[:min_size]} is not identical to min pool size #{options[:min_pool_size]}"
|
|
109
107
|
end
|
|
110
108
|
if options[:max_size] && options[:max_pool_size] && options[:max_size] != options[:max_pool_size]
|
|
111
|
-
raise ArgumentError,
|
|
109
|
+
raise ArgumentError,
|
|
110
|
+
"Max size #{options[:max_size]} is not identical to max pool size #{options[:max_pool_size]}"
|
|
112
111
|
end
|
|
113
112
|
if options[:wait_timeout] && options[:wait_queue_timeout] && options[:wait_timeout] != options[:wait_queue_timeout]
|
|
114
|
-
raise ArgumentError,
|
|
113
|
+
raise ArgumentError,
|
|
114
|
+
"Wait timeout #{options[:wait_timeout]} is not identical to wait queue timeout #{options[:wait_queue_timeout]}"
|
|
115
115
|
end
|
|
116
|
+
|
|
116
117
|
options[:min_size] ||= options[:min_pool_size]
|
|
117
118
|
options.delete(:min_pool_size)
|
|
118
119
|
options[:max_size] ||= options[:max_pool_size]
|
|
119
120
|
options.delete(:max_pool_size)
|
|
120
121
|
if options[:min_size] && options[:max_size] &&
|
|
121
|
-
|
|
122
|
-
then
|
|
122
|
+
options[:max_size] != 0 && options[:min_size] > options[:max_size]
|
|
123
123
|
raise ArgumentError, "Cannot have min size #{options[:min_size]} exceed max size #{options[:max_size]}"
|
|
124
124
|
end
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
end
|
|
125
|
+
|
|
126
|
+
options[:wait_timeout] ||= options[:wait_queue_timeout] if options[:wait_queue_timeout]
|
|
128
127
|
options.delete(:wait_queue_timeout)
|
|
129
128
|
|
|
130
129
|
@server = server
|
|
@@ -137,18 +136,25 @@ module Mongo
|
|
|
137
136
|
# A connection owned by this pool should be either in the
|
|
138
137
|
# available connections array (which is used as a stack)
|
|
139
138
|
# or in the checked out connections set.
|
|
140
|
-
@available_connections =
|
|
139
|
+
@available_connections = []
|
|
141
140
|
@checked_out_connections = Set.new
|
|
142
141
|
@pending_connections = Set.new
|
|
143
142
|
@interrupt_connections = []
|
|
144
143
|
|
|
144
|
+
# RUBY-3364: count threads currently blocked on size_cv /
|
|
145
|
+
# max_connecting_cv. When non-zero, a newly-arriving thread must
|
|
146
|
+
# enter the wait queue even if the gate predicate is currently
|
|
147
|
+
# satisfied, to prevent barging past existing waiters.
|
|
148
|
+
@size_waiters = 0
|
|
149
|
+
@max_connecting_waiters = 0
|
|
150
|
+
|
|
145
151
|
# Mutex used for synchronizing access to @available_connections and
|
|
146
152
|
# @checked_out_connections. The pool object is thread-safe, thus
|
|
147
153
|
# all methods that retrieve or modify instance variables generally
|
|
148
154
|
# must do so under this lock.
|
|
149
155
|
@lock = Mutex.new
|
|
150
156
|
|
|
151
|
-
# Background thread
|
|
157
|
+
# Background thread responsible for maintaining the size of
|
|
152
158
|
# the pool to at least min_size
|
|
153
159
|
@populator = Populator.new(self, options)
|
|
154
160
|
@populate_semaphore = Semaphore.new
|
|
@@ -164,12 +170,13 @@ module Mongo
|
|
|
164
170
|
@connection_requests = 0
|
|
165
171
|
|
|
166
172
|
# Condition variable to enforce the second check in check_out: max_connecting.
|
|
167
|
-
#
|
|
173
|
+
# This condition variable should be signaled when the number of pending
|
|
168
174
|
# connections decreases.
|
|
169
175
|
@max_connecting_cv = Mongo::ConditionVariable.new(@lock)
|
|
170
176
|
@max_connecting = options.fetch(:max_connecting, DEFAULT_MAX_CONNECTING)
|
|
171
177
|
|
|
172
|
-
ObjectSpace.define_finalizer(self,
|
|
178
|
+
ObjectSpace.define_finalizer(self,
|
|
179
|
+
self.class.finalize(@available_connections, @pending_connections, @populator))
|
|
173
180
|
|
|
174
181
|
publish_cmap_event(
|
|
175
182
|
Monitoring::Event::Cmap::PoolCreated.new(@server.address, options, self)
|
|
@@ -191,7 +198,7 @@ module Mongo
|
|
|
191
198
|
#
|
|
192
199
|
# @since 2.9.0
|
|
193
200
|
def max_size
|
|
194
|
-
@max_size ||= options[:max_size] || [DEFAULT_MAX_SIZE, min_size].max
|
|
201
|
+
@max_size ||= options[:max_size] || [ DEFAULT_MAX_SIZE, min_size ].max
|
|
195
202
|
end
|
|
196
203
|
|
|
197
204
|
# Get the minimum size of the connection pool.
|
|
@@ -321,12 +328,12 @@ module Mongo
|
|
|
321
328
|
def summary
|
|
322
329
|
@lock.synchronize do
|
|
323
330
|
state = if closed?
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
331
|
+
'closed'
|
|
332
|
+
elsif !@ready
|
|
333
|
+
'paused'
|
|
334
|
+
else
|
|
335
|
+
'ready'
|
|
336
|
+
end
|
|
330
337
|
"#<ConnectionPool size=#{unsynchronized_size} (#{min_size}-#{max_size}) " +
|
|
331
338
|
"used=#{@checked_out_connections.length} avail=#{@available_connections.length} pending=#{@pending_connections.length} #{state}>"
|
|
332
339
|
end
|
|
@@ -378,13 +385,12 @@ module Mongo
|
|
|
378
385
|
)
|
|
379
386
|
|
|
380
387
|
publish_cmap_event(
|
|
381
|
-
Monitoring::Event::Cmap::ConnectionCheckedOut.new(@server.address, connection.id, self)
|
|
388
|
+
Monitoring::Event::Cmap::ConnectionCheckedOut.new(@server.address, connection.id, self)
|
|
382
389
|
)
|
|
383
390
|
|
|
384
|
-
if Lint.enabled?
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
end
|
|
391
|
+
if Lint.enabled? && !connection.connected?
|
|
392
|
+
raise Error::LintError,
|
|
393
|
+
"Connection pool for #{address} checked out a disconnected connection #{connection.generation}:#{connection.id}"
|
|
388
394
|
end
|
|
389
395
|
|
|
390
396
|
connection
|
|
@@ -392,6 +398,23 @@ module Mongo
|
|
|
392
398
|
check_invariants
|
|
393
399
|
end
|
|
394
400
|
|
|
401
|
+
# Returns a pinned connection that is already checked out, if one
|
|
402
|
+
# exists with the given global id. Returns nil otherwise.
|
|
403
|
+
#
|
|
404
|
+
# @param [ Integer ] connection_global_id The global id of the pinned
|
|
405
|
+
# connection.
|
|
406
|
+
#
|
|
407
|
+
# @return [ Connection | nil ] The pinned connection, or nil.
|
|
408
|
+
#
|
|
409
|
+
# @api private
|
|
410
|
+
def check_out_pinned_connection(connection_global_id)
|
|
411
|
+
@lock.synchronize do
|
|
412
|
+
@checked_out_connections.detect do |conn|
|
|
413
|
+
conn.global_id == connection_global_id && conn.pinned?
|
|
414
|
+
end
|
|
415
|
+
end
|
|
416
|
+
end
|
|
417
|
+
|
|
395
418
|
# Check a connection back into the pool.
|
|
396
419
|
#
|
|
397
420
|
# The connection must have been previously created by this pool.
|
|
@@ -420,14 +443,16 @@ module Mongo
|
|
|
420
443
|
return if connection.closed? && connection.interrupted?
|
|
421
444
|
|
|
422
445
|
unless connection.connection_pool == self
|
|
423
|
-
raise ArgumentError,
|
|
446
|
+
raise ArgumentError,
|
|
447
|
+
"Trying to check in a connection which was not checked out by this pool: #{connection} checked out from pool #{connection.connection_pool} (for #{self})"
|
|
424
448
|
end
|
|
425
449
|
|
|
426
450
|
unless @checked_out_connections.include?(connection)
|
|
427
|
-
raise ArgumentError,
|
|
451
|
+
raise ArgumentError,
|
|
452
|
+
"Trying to check in a connection which is not currently checked out by this pool: #{connection} (for #{self})"
|
|
428
453
|
end
|
|
429
454
|
|
|
430
|
-
#
|
|
455
|
+
# NOTE: if an event handler raises, resource will not be signaled.
|
|
431
456
|
# This means threads waiting for a connection to free up when
|
|
432
457
|
# the pool is at max size may time out.
|
|
433
458
|
# Threads that begin waiting after this method completes (with
|
|
@@ -495,7 +520,7 @@ module Mongo
|
|
|
495
520
|
raise Error::LintError, "Attempting to pause pool for server #{@server.summary} which is known"
|
|
496
521
|
end
|
|
497
522
|
|
|
498
|
-
return
|
|
523
|
+
return unless @ready
|
|
499
524
|
|
|
500
525
|
@ready = false
|
|
501
526
|
end
|
|
@@ -551,9 +576,7 @@ module Mongo
|
|
|
551
576
|
# Generation must be bumped before emitting pool cleared event.
|
|
552
577
|
@generation_manager.bump(service_id: service_id)
|
|
553
578
|
|
|
554
|
-
unless options && options[:lazy]
|
|
555
|
-
close_available_connections(service_id)
|
|
556
|
-
end
|
|
579
|
+
close_available_connections(service_id) unless options && options[:lazy]
|
|
557
580
|
|
|
558
581
|
if options && options[:interrupt_in_use_connections]
|
|
559
582
|
schedule_for_interruption(@checked_out_connections, service_id)
|
|
@@ -618,12 +641,12 @@ module Mongo
|
|
|
618
641
|
Monitoring::Event::Cmap::PoolReady.new(@server.address, options, self)
|
|
619
642
|
)
|
|
620
643
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
644
|
+
return unless options.fetch(:populator_io, true)
|
|
645
|
+
|
|
646
|
+
if @populator.running?
|
|
647
|
+
@populate_semaphore.signal
|
|
648
|
+
else
|
|
649
|
+
@populator.run!
|
|
627
650
|
end
|
|
628
651
|
end
|
|
629
652
|
|
|
@@ -715,16 +738,35 @@ module Mongo
|
|
|
715
738
|
def with_connection(connection_global_id: nil, context: nil)
|
|
716
739
|
raise_if_closed!
|
|
717
740
|
|
|
718
|
-
connection
|
|
741
|
+
# If a specific connection is requested and it is already checked out
|
|
742
|
+
# and pinned (e.g. for a transaction or cursor in load-balanced mode),
|
|
743
|
+
# reuse it directly without going through the check_out/check_in cycle.
|
|
744
|
+
if connection_global_id
|
|
745
|
+
connection = @lock.synchronize do
|
|
746
|
+
@checked_out_connections.detect do |conn|
|
|
747
|
+
conn.global_id == connection_global_id && conn.pinned?
|
|
748
|
+
end
|
|
749
|
+
end
|
|
750
|
+
end
|
|
751
|
+
|
|
752
|
+
connection ||= check_out(
|
|
719
753
|
connection_global_id: connection_global_id,
|
|
720
754
|
context: context
|
|
721
755
|
)
|
|
756
|
+
|
|
722
757
|
yield(connection)
|
|
723
758
|
rescue Error::SocketError, Error::SocketTimeoutError, Error::ConnectionPerished => e
|
|
724
759
|
maybe_raise_pool_cleared!(connection, e)
|
|
725
760
|
ensure
|
|
726
|
-
if connection
|
|
727
|
-
|
|
761
|
+
if connection && !connection.pinned?
|
|
762
|
+
# Do not check in if the connection is pinned (the session or cursor
|
|
763
|
+
# owns it and will check it in later when unpinning). Also skip
|
|
764
|
+
# check-in if the connection was already checked in during the block
|
|
765
|
+
# (e.g. by Session#unpin after an error on the first operation).
|
|
766
|
+
checked_out = @lock.synchronize do
|
|
767
|
+
@checked_out_connections.include?(connection)
|
|
768
|
+
end
|
|
769
|
+
check_in(connection) if checked_out
|
|
728
770
|
end
|
|
729
771
|
end
|
|
730
772
|
|
|
@@ -740,13 +782,11 @@ module Mongo
|
|
|
740
782
|
i = 0
|
|
741
783
|
while i < @available_connections.length
|
|
742
784
|
connection = @available_connections[i]
|
|
743
|
-
if last_checkin = connection.last_checkin
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
next
|
|
749
|
-
end
|
|
785
|
+
if (last_checkin = connection.last_checkin) && ((Time.now - last_checkin) > max_idle_time)
|
|
786
|
+
connection.disconnect!(reason: :idle)
|
|
787
|
+
@available_connections.delete_at(i)
|
|
788
|
+
@populate_semaphore.signal
|
|
789
|
+
next
|
|
750
790
|
end
|
|
751
791
|
i += 1
|
|
752
792
|
end
|
|
@@ -787,7 +827,7 @@ module Mongo
|
|
|
787
827
|
# @return [ true | false ] Whether this method should be called again
|
|
788
828
|
# to create more connections.
|
|
789
829
|
# @raise [ Error::AuthError, Error ] The second socket-related error raised if a retry
|
|
790
|
-
#
|
|
830
|
+
# occurred, or the non socket-related error
|
|
791
831
|
#
|
|
792
832
|
# @api private
|
|
793
833
|
def populate
|
|
@@ -801,7 +841,7 @@ module Mongo
|
|
|
801
841
|
log_warn("Populator failed to connect a connection for #{address}: #{e.class}: #{e}. It will retry.")
|
|
802
842
|
end
|
|
803
843
|
|
|
804
|
-
|
|
844
|
+
create_and_add_connection
|
|
805
845
|
end
|
|
806
846
|
|
|
807
847
|
# Finalize the connection pool for garbage collection.
|
|
@@ -811,7 +851,7 @@ module Mongo
|
|
|
811
851
|
# @param [ Populator ] populator The populator.
|
|
812
852
|
#
|
|
813
853
|
# @return [ Proc ] The Finalizer.
|
|
814
|
-
def self.finalize(available_connections, pending_connections,
|
|
854
|
+
def self.finalize(available_connections, pending_connections, _populator)
|
|
815
855
|
proc do
|
|
816
856
|
available_connections.each do |connection|
|
|
817
857
|
connection.disconnect!(reason: :pool_closed)
|
|
@@ -841,9 +881,7 @@ module Mongo
|
|
|
841
881
|
conn = @available_connections.detect do |conn|
|
|
842
882
|
conn.global_id == connection_global_id
|
|
843
883
|
end
|
|
844
|
-
if conn
|
|
845
|
-
@available_connections.delete(conn)
|
|
846
|
-
end
|
|
884
|
+
@available_connections.delete(conn) if conn
|
|
847
885
|
conn
|
|
848
886
|
else
|
|
849
887
|
@available_connections.pop
|
|
@@ -851,16 +889,14 @@ module Mongo
|
|
|
851
889
|
end
|
|
852
890
|
|
|
853
891
|
def create_connection
|
|
854
|
-
r,
|
|
892
|
+
r, = @generation_manager.pipe_fds(service_id: server.description.service_id)
|
|
855
893
|
opts = options.merge(
|
|
856
894
|
connection_pool: self,
|
|
857
895
|
pipe: r
|
|
858
896
|
# Do not pass app metadata - this will be retrieved by the connection
|
|
859
897
|
# based on the auth needs.
|
|
860
898
|
)
|
|
861
|
-
unless @server.load_balancer?
|
|
862
|
-
opts[:generation] = generation
|
|
863
|
-
end
|
|
899
|
+
opts[:generation] = generation unless @server.load_balancer?
|
|
864
900
|
Connection.new(@server, opts)
|
|
865
901
|
end
|
|
866
902
|
|
|
@@ -875,14 +911,14 @@ module Mongo
|
|
|
875
911
|
|
|
876
912
|
@lock.synchronize do
|
|
877
913
|
if !closed? && @ready &&
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
then
|
|
914
|
+
(unsynchronized_size + @connection_requests) < min_size &&
|
|
915
|
+
@pending_connections.length < @max_connecting
|
|
881
916
|
connection = create_connection
|
|
882
917
|
@pending_connections << connection
|
|
883
918
|
else
|
|
884
919
|
return true if remove_interrupted_connections
|
|
885
920
|
return true if remove_stale_connection
|
|
921
|
+
|
|
886
922
|
return false
|
|
887
923
|
end
|
|
888
924
|
end
|
|
@@ -910,11 +946,11 @@ module Mongo
|
|
|
910
946
|
|
|
911
947
|
# Removes and disconnects all stale available connections.
|
|
912
948
|
def remove_stale_connection
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
949
|
+
return unless conn = @available_connections.detect { |c| connection_stale_unlocked?(c) }
|
|
950
|
+
|
|
951
|
+
conn.disconnect!(reason: :stale)
|
|
952
|
+
@available_connections.delete(conn)
|
|
953
|
+
true
|
|
918
954
|
end
|
|
919
955
|
|
|
920
956
|
# Interrupt connections scheduled for interruption.
|
|
@@ -957,7 +993,7 @@ module Mongo
|
|
|
957
993
|
# @return [ true | false ] Whether the connection is stale.
|
|
958
994
|
def connection_stale_unlocked?(connection)
|
|
959
995
|
connection.generation != generation_unlocked(service_id: connection.service_id) &&
|
|
960
|
-
|
|
996
|
+
!connection.pinned?
|
|
961
997
|
end
|
|
962
998
|
|
|
963
999
|
# Asserts that the pool has not been closed.
|
|
@@ -966,9 +1002,9 @@ module Mongo
|
|
|
966
1002
|
#
|
|
967
1003
|
# @since 2.9.0
|
|
968
1004
|
def raise_if_closed!
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
1005
|
+
return unless closed?
|
|
1006
|
+
|
|
1007
|
+
raise Error::PoolClosedError.new(@server.address, self)
|
|
972
1008
|
end
|
|
973
1009
|
|
|
974
1010
|
# If the connection was interrupted, raise a pool cleared error. If it
|
|
@@ -980,31 +1016,36 @@ module Mongo
|
|
|
980
1016
|
# @raise [ Mongo::Error | Mongo::Error::PoolClearedError ] A PoolClearedError
|
|
981
1017
|
# if the connection was interrupted, the original error if not.
|
|
982
1018
|
def maybe_raise_pool_cleared!(connection, e)
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
raise err
|
|
988
|
-
else
|
|
989
|
-
raise e
|
|
1019
|
+
raise e unless connection&.interrupted?
|
|
1020
|
+
|
|
1021
|
+
err = Error::PoolClearedError.new(connection.server.address, connection.server.pool_internal).tap do |err|
|
|
1022
|
+
e.labels.each { |l| err.add_label(l) }
|
|
990
1023
|
end
|
|
1024
|
+
raise err
|
|
991
1025
|
end
|
|
992
1026
|
|
|
993
1027
|
# Attempts to connect (handshake and auth) the connection. If an error is
|
|
994
1028
|
# encountered, closes the connection and raises the error.
|
|
995
1029
|
def connect_connection(connection, context = nil)
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1030
|
+
connection.connect!(context)
|
|
1031
|
+
rescue Exception => e
|
|
1032
|
+
# When a connection encounters an error during creation
|
|
1033
|
+
# (including handshake and authentication), mark the server
|
|
1034
|
+
# as Unknown so the pool is cleared (per CMAP spec).
|
|
1035
|
+
# The unknown! call must happen before disconnect! so that
|
|
1036
|
+
# the ConnectionPoolCleared event is published before the
|
|
1037
|
+
# ConnectionClosed event.
|
|
1038
|
+
# Errors with the SystemOverloadedError label (network errors
|
|
1039
|
+
# during handshake) are excluded per the SDAM spec — those
|
|
1040
|
+
# must not change the server description.
|
|
1041
|
+
if e.is_a?(Mongo::Error) && !e.label?('SystemOverloadedError')
|
|
1042
|
+
@server.unknown!(
|
|
1043
|
+
generation: e.generation,
|
|
1044
|
+
service_id: e.service_id,
|
|
1045
|
+
stop_push_monitor: true
|
|
1046
|
+
)
|
|
1001
1047
|
end
|
|
1002
|
-
|
|
1003
|
-
@server.unknown!(
|
|
1004
|
-
generation: exc.generation,
|
|
1005
|
-
service_id: exc.service_id,
|
|
1006
|
-
stop_push_monitor: true,
|
|
1007
|
-
)
|
|
1048
|
+
connection.disconnect!(reason: :error)
|
|
1008
1049
|
raise
|
|
1009
1050
|
end
|
|
1010
1051
|
|
|
@@ -1039,15 +1080,13 @@ module Mongo
|
|
|
1039
1080
|
loop do
|
|
1040
1081
|
conn = @available_connections.detect do |conn|
|
|
1041
1082
|
conn.service_id == service_id &&
|
|
1042
|
-
|
|
1043
|
-
end
|
|
1044
|
-
if conn
|
|
1045
|
-
@available_connections.delete(conn)
|
|
1046
|
-
conn.disconnect!(reason: :stale, interrupted: true)
|
|
1047
|
-
@populate_semaphore.signal
|
|
1048
|
-
else
|
|
1049
|
-
break
|
|
1083
|
+
conn.generation < @generation_manager.generation(service_id: service_id)
|
|
1050
1084
|
end
|
|
1085
|
+
break unless conn
|
|
1086
|
+
|
|
1087
|
+
@available_connections.delete(conn)
|
|
1088
|
+
conn.disconnect!(reason: :stale, interrupted: true)
|
|
1089
|
+
@populate_semaphore.signal
|
|
1051
1090
|
end
|
|
1052
1091
|
else
|
|
1053
1092
|
@available_connections.delete_if do |conn|
|
|
@@ -1067,7 +1106,7 @@ module Mongo
|
|
|
1067
1106
|
def schedule_for_interruption(connections, service_id)
|
|
1068
1107
|
@interrupt_connections += connections.select do |conn|
|
|
1069
1108
|
(!server.load_balancer? || conn.service_id == service_id) &&
|
|
1070
|
-
|
|
1109
|
+
conn.generation < @generation_manager.generation(service_id: service_id)
|
|
1071
1110
|
end
|
|
1072
1111
|
end
|
|
1073
1112
|
|
|
@@ -1087,23 +1126,23 @@ module Mongo
|
|
|
1087
1126
|
publish_cmap_event(
|
|
1088
1127
|
Monitoring::Event::Cmap::ConnectionCheckOutFailed.new(
|
|
1089
1128
|
@server.address,
|
|
1090
|
-
Monitoring::Event::Cmap::ConnectionCheckOutFailed::TIMEOUT
|
|
1091
|
-
)
|
|
1129
|
+
Monitoring::Event::Cmap::ConnectionCheckOutFailed::TIMEOUT
|
|
1130
|
+
)
|
|
1092
1131
|
)
|
|
1093
1132
|
|
|
1094
1133
|
connection_global_id_msg = if connection_global_id
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
msg =
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1134
|
+
" for connection #{connection_global_id}"
|
|
1135
|
+
else
|
|
1136
|
+
''
|
|
1137
|
+
end
|
|
1138
|
+
|
|
1139
|
+
msg = 'Timed out attempting to check out a connection ' +
|
|
1140
|
+
"from pool for #{@server.address}#{connection_global_id_msg} after #{wait_timeout} sec. " +
|
|
1141
|
+
"Connections in pool: #{@available_connections.length} available, " +
|
|
1142
|
+
"#{@checked_out_connections.length} checked out, " +
|
|
1143
|
+
"#{@pending_connections.length} pending, " +
|
|
1144
|
+
"#{@connection_requests} connections requests " +
|
|
1145
|
+
"(max size: #{max_size})"
|
|
1107
1146
|
raise Error::ConnectionCheckOutTimeout.new(msg, address: @server.address)
|
|
1108
1147
|
end
|
|
1109
1148
|
|
|
@@ -1114,31 +1153,31 @@ module Mongo
|
|
|
1114
1153
|
end
|
|
1115
1154
|
|
|
1116
1155
|
def raise_if_pool_closed!
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1156
|
+
return unless closed?
|
|
1157
|
+
|
|
1158
|
+
publish_cmap_event(
|
|
1159
|
+
Monitoring::Event::Cmap::ConnectionCheckOutFailed.new(
|
|
1160
|
+
@server.address,
|
|
1161
|
+
Monitoring::Event::Cmap::ConnectionCheckOutFailed::POOL_CLOSED
|
|
1123
1162
|
)
|
|
1124
|
-
|
|
1125
|
-
|
|
1163
|
+
)
|
|
1164
|
+
raise Error::PoolClosedError.new(@server.address, self)
|
|
1126
1165
|
end
|
|
1127
1166
|
|
|
1128
1167
|
def raise_if_pool_paused!
|
|
1129
1168
|
raise_unless_locked!
|
|
1130
1169
|
|
|
1131
|
-
if
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1170
|
+
return if @ready
|
|
1171
|
+
|
|
1172
|
+
publish_cmap_event(
|
|
1173
|
+
Monitoring::Event::Cmap::ConnectionCheckOutFailed.new(
|
|
1174
|
+
@server.address,
|
|
1175
|
+
# CMAP spec decided to conflate pool paused with all the other
|
|
1176
|
+
# possible non-timeout errors.
|
|
1177
|
+
Monitoring::Event::Cmap::ConnectionCheckOutFailed::CONNECTION_ERROR
|
|
1139
1178
|
)
|
|
1140
|
-
|
|
1141
|
-
|
|
1179
|
+
)
|
|
1180
|
+
raise Error::PoolPausedError.new(@server.address, self)
|
|
1142
1181
|
end
|
|
1143
1182
|
|
|
1144
1183
|
def raise_if_pool_paused_locked!
|
|
@@ -1155,12 +1194,12 @@ module Mongo
|
|
|
1155
1194
|
end
|
|
1156
1195
|
|
|
1157
1196
|
def raise_unless_locked!
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1197
|
+
return if @lock.owned?
|
|
1198
|
+
|
|
1199
|
+
raise ArgumentError, 'the lock must be owned when calling this method'
|
|
1161
1200
|
end
|
|
1162
1201
|
|
|
1163
|
-
def valid_available_connection?(connection, pid,
|
|
1202
|
+
def valid_available_connection?(connection, pid, _connection_global_id)
|
|
1164
1203
|
if connection.pid != pid
|
|
1165
1204
|
log_warn("Detected PID change - Mongo client should have been reconnected (old pid #{connection.pid}, new pid #{pid}")
|
|
1166
1205
|
connection.disconnect!(reason: :stale)
|
|
@@ -1168,7 +1207,7 @@ module Mongo
|
|
|
1168
1207
|
return false
|
|
1169
1208
|
end
|
|
1170
1209
|
|
|
1171
|
-
|
|
1210
|
+
unless connection.pinned?
|
|
1172
1211
|
# If connection is marked as pinned, it is used by a transaction
|
|
1173
1212
|
# or a series of cursor operations in a load balanced setup.
|
|
1174
1213
|
# In this case connection should not be disconnected until
|
|
@@ -1184,8 +1223,7 @@ module Mongo
|
|
|
1184
1223
|
end
|
|
1185
1224
|
|
|
1186
1225
|
if max_idle_time && connection.last_checkin &&
|
|
1187
|
-
|
|
1188
|
-
then
|
|
1226
|
+
Time.now - connection.last_checkin > max_idle_time
|
|
1189
1227
|
connection.disconnect!(reason: :idle)
|
|
1190
1228
|
@populate_semaphore.signal
|
|
1191
1229
|
return false
|
|
@@ -1209,9 +1247,7 @@ module Mongo
|
|
|
1209
1247
|
# and remains so for longer than the wait timeout.
|
|
1210
1248
|
def get_connection(pid, connection_global_id)
|
|
1211
1249
|
if connection = next_available_connection(connection_global_id)
|
|
1212
|
-
unless valid_available_connection?(connection, pid, connection_global_id)
|
|
1213
|
-
return nil
|
|
1214
|
-
end
|
|
1250
|
+
return nil unless valid_available_connection?(connection, pid, connection_global_id)
|
|
1215
1251
|
|
|
1216
1252
|
# We've got a connection, so we decrement the number of connection
|
|
1217
1253
|
# requests.
|
|
@@ -1222,13 +1258,11 @@ module Mongo
|
|
|
1222
1258
|
# If the connection is connected, it's not considered a
|
|
1223
1259
|
# "pending connection". The pending_connections list represents
|
|
1224
1260
|
# the set of connections that are awaiting connection.
|
|
1225
|
-
unless connection.connected?
|
|
1226
|
-
|
|
1227
|
-
end
|
|
1228
|
-
return connection
|
|
1261
|
+
@pending_connections << connection unless connection.connected?
|
|
1262
|
+
connection
|
|
1229
1263
|
elsif connection_global_id && @server.load_balancer?
|
|
1230
1264
|
# A particular connection is requested, but it is not available.
|
|
1231
|
-
# If it is
|
|
1265
|
+
# If it is neither available nor checked out, we should stop here.
|
|
1232
1266
|
@checked_out_connections.detect do |conn|
|
|
1233
1267
|
conn.global_id == connection_global_id
|
|
1234
1268
|
end.tap do |conn|
|
|
@@ -1237,7 +1271,7 @@ module Mongo
|
|
|
1237
1271
|
Monitoring::Event::Cmap::ConnectionCheckOutFailed.new(
|
|
1238
1272
|
@server.address,
|
|
1239
1273
|
Monitoring::Event::Cmap::ConnectionCheckOutFailed::CONNECTION_ERROR
|
|
1240
|
-
)
|
|
1274
|
+
)
|
|
1241
1275
|
)
|
|
1242
1276
|
# We're going to raise, so we need to decrement the number of
|
|
1243
1277
|
# connection requests.
|
|
@@ -1253,7 +1287,7 @@ module Mongo
|
|
|
1253
1287
|
connection = create_connection
|
|
1254
1288
|
@connection_requests -= 1
|
|
1255
1289
|
@pending_connections << connection
|
|
1256
|
-
|
|
1290
|
+
connection
|
|
1257
1291
|
end
|
|
1258
1292
|
end
|
|
1259
1293
|
|
|
@@ -1269,18 +1303,32 @@ module Mongo
|
|
|
1269
1303
|
# @raise [ Error::PoolClosedError ] If the pool has been closed.
|
|
1270
1304
|
# @raise [ Timeout::Error ] If the connection pool is at maximum size
|
|
1271
1305
|
# and remains so for longer than the wait timeout.
|
|
1272
|
-
def retrieve_and_connect_connection(connection_global_id, context =
|
|
1306
|
+
def retrieve_and_connect_connection(connection_global_id, context = nil)
|
|
1273
1307
|
deadline = Utils.monotonic_time + wait_timeout(context)
|
|
1274
1308
|
connection = nil
|
|
1275
1309
|
|
|
1276
1310
|
@lock.synchronize do
|
|
1277
|
-
#
|
|
1278
|
-
#
|
|
1279
|
-
|
|
1311
|
+
# RUBY-3364: if any thread is already waiting for a size slot,
|
|
1312
|
+
# join the queue even when the gate predicate is currently
|
|
1313
|
+
# satisfied. Without this, re-entering threads (those that just
|
|
1314
|
+
# checked a connection back in) barge past existing waiters and
|
|
1315
|
+
# the 195 blocked threads in a 200:5 scenario never wake.
|
|
1316
|
+
# Skip the gate for unlimited pools (max_size == 0) where there
|
|
1317
|
+
# is no size constraint to wait on.
|
|
1318
|
+
must_wait = max_size != 0 && @size_waiters > 0
|
|
1319
|
+
until (max_size == 0 || unavailable_connections < max_size) && !must_wait
|
|
1280
1320
|
wait = deadline - Utils.monotonic_time
|
|
1281
1321
|
raise_check_out_timeout!(connection_global_id) if wait <= 0
|
|
1282
|
-
@
|
|
1322
|
+
@size_waiters += 1
|
|
1323
|
+
begin
|
|
1324
|
+
@size_cv.wait(wait)
|
|
1325
|
+
ensure
|
|
1326
|
+
@size_waiters -= 1
|
|
1327
|
+
end
|
|
1283
1328
|
raise_if_not_ready!
|
|
1329
|
+
# After one wait cycle we have served our "queue tax" and
|
|
1330
|
+
# compete for the slot on the next predicate check.
|
|
1331
|
+
must_wait = false
|
|
1284
1332
|
end
|
|
1285
1333
|
@connection_requests += 1
|
|
1286
1334
|
connection = wait_for_connection(connection_global_id, deadline)
|
|
@@ -1290,15 +1338,28 @@ module Mongo
|
|
|
1290
1338
|
|
|
1291
1339
|
@lock.synchronize do
|
|
1292
1340
|
@checked_out_connections << connection
|
|
1293
|
-
if @pending_connections.include?(connection)
|
|
1294
|
-
@pending_connections.delete(connection)
|
|
1295
|
-
end
|
|
1341
|
+
@pending_connections.delete(connection) if @pending_connections.include?(connection)
|
|
1296
1342
|
@max_connecting_cv.signal
|
|
1297
|
-
#
|
|
1298
|
-
#
|
|
1343
|
+
# RUBY-3364: hand off the baton. A waiter that arrived during
|
|
1344
|
+
# our wake-up window (seeing our stale @size_waiters > 0) may be
|
|
1345
|
+
# parked on @size_cv with capacity already available. The
|
|
1346
|
+
# regular check-in path is the only other place that signals
|
|
1347
|
+
# @size_cv, so we wake the next waiter only when the predicate
|
|
1348
|
+
# is actually satisfied for them. Signaling unconditionally
|
|
1349
|
+
# would re-queue a waiter at the back of the FIFO and break
|
|
1350
|
+
# ordering.
|
|
1351
|
+
if @size_waiters > 0 && (max_size == 0 || unavailable_connections < max_size)
|
|
1352
|
+
@size_cv.signal
|
|
1353
|
+
end
|
|
1299
1354
|
end
|
|
1300
1355
|
|
|
1301
1356
|
connection
|
|
1357
|
+
rescue Error::ConnectionCheckOutTimeout
|
|
1358
|
+
# Per the CSOT spec, if a connection checkout fails because the CSOT
|
|
1359
|
+
# deadline expired (rather than a configured waitQueueTimeout), the
|
|
1360
|
+
# error must be a CSOT TimeoutError so that callers can distinguish it.
|
|
1361
|
+
context&.check_timeout!
|
|
1362
|
+
raise
|
|
1302
1363
|
end
|
|
1303
1364
|
|
|
1304
1365
|
# Waits for a connection to become available, or raises is no connection
|
|
@@ -1311,9 +1372,12 @@ module Mongo
|
|
|
1311
1372
|
def wait_for_connection(connection_global_id, deadline)
|
|
1312
1373
|
connection = nil
|
|
1313
1374
|
while connection.nil?
|
|
1375
|
+
# RUBY-3364: as above, yield to any thread already queued for
|
|
1376
|
+
# a max_connecting slot before competing ourselves.
|
|
1377
|
+
must_wait = @max_connecting_waiters > 0
|
|
1314
1378
|
# The second gate to checking out a connection. Make sure 1) there
|
|
1315
1379
|
# exists an available connection and 2) we are under max_connecting.
|
|
1316
|
-
until @available_connections.any? || @pending_connections.length < @max_connecting
|
|
1380
|
+
until (@available_connections.any? || @pending_connections.length < @max_connecting) && !must_wait
|
|
1317
1381
|
wait = deadline - Utils.monotonic_time
|
|
1318
1382
|
if wait <= 0
|
|
1319
1383
|
# We are going to raise a timeout error, so the connection
|
|
@@ -1322,21 +1386,35 @@ module Mongo
|
|
|
1322
1386
|
decrement_connection_requests_and_signal
|
|
1323
1387
|
raise_check_out_timeout!(connection_global_id)
|
|
1324
1388
|
end
|
|
1325
|
-
@
|
|
1389
|
+
@max_connecting_waiters += 1
|
|
1390
|
+
begin
|
|
1391
|
+
@max_connecting_cv.wait(wait)
|
|
1392
|
+
ensure
|
|
1393
|
+
@max_connecting_waiters -= 1
|
|
1394
|
+
end
|
|
1326
1395
|
# We do not need to decrement the connection_requests counter
|
|
1327
1396
|
# or signal here because the pool is not ready yet.
|
|
1328
1397
|
raise_if_not_ready!
|
|
1398
|
+
must_wait = false
|
|
1329
1399
|
end
|
|
1330
1400
|
|
|
1331
1401
|
connection = get_connection(Process.pid, connection_global_id)
|
|
1332
1402
|
wait = deadline - Utils.monotonic_time
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1403
|
+
next unless connection.nil? && wait <= 0
|
|
1404
|
+
|
|
1405
|
+
# connection is nil here, it means that get_connection method
|
|
1406
|
+
# did not create a new connection; therefore, it did not decrease
|
|
1407
|
+
# the connection_requests counter. We need to do it here.
|
|
1408
|
+
decrement_connection_requests_and_signal
|
|
1409
|
+
raise_check_out_timeout!(connection_global_id)
|
|
1410
|
+
end
|
|
1411
|
+
|
|
1412
|
+
# RUBY-3364: hand off the baton for max_connecting_cv. Signal
|
|
1413
|
+
# only if the gate predicate is satisfied for the next waiter, to
|
|
1414
|
+
# avoid re-queuing a waiter at the back of the FIFO.
|
|
1415
|
+
if @max_connecting_waiters > 0 &&
|
|
1416
|
+
(@available_connections.any? || @pending_connections.length < @max_connecting)
|
|
1417
|
+
@max_connecting_cv.signal
|
|
1340
1418
|
end
|
|
1341
1419
|
|
|
1342
1420
|
connection
|
|
@@ -1351,9 +1429,7 @@ module Mongo
|
|
|
1351
1429
|
rescue Exception
|
|
1352
1430
|
# Handshake or authentication failed
|
|
1353
1431
|
@lock.synchronize do
|
|
1354
|
-
if @pending_connections.include?(connection)
|
|
1355
|
-
@pending_connections.delete(connection)
|
|
1356
|
-
end
|
|
1432
|
+
@pending_connections.delete(connection) if @pending_connections.include?(connection)
|
|
1357
1433
|
@max_connecting_cv.signal
|
|
1358
1434
|
@size_cv.signal
|
|
1359
1435
|
end
|
|
@@ -1362,12 +1438,11 @@ module Mongo
|
|
|
1362
1438
|
Monitoring::Event::Cmap::ConnectionCheckOutFailed.new(
|
|
1363
1439
|
@server.address,
|
|
1364
1440
|
Monitoring::Event::Cmap::ConnectionCheckOutFailed::CONNECTION_ERROR
|
|
1365
|
-
)
|
|
1441
|
+
)
|
|
1366
1442
|
)
|
|
1367
1443
|
raise
|
|
1368
1444
|
end
|
|
1369
1445
|
|
|
1370
|
-
|
|
1371
1446
|
# Decrement connection requests counter and signal the condition
|
|
1372
1447
|
# variables that the number of unavailable connections has decreased.
|
|
1373
1448
|
def decrement_connection_requests_and_signal
|