mongo 2.19.1 → 2.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +40 -1
- data/Rakefile +83 -174
- data/lib/mongo/address.rb +22 -3
- data/lib/mongo/auth/aws/credentials_retriever.rb +70 -17
- data/lib/mongo/auth/base.rb +1 -1
- data/lib/mongo/bulk_write.rb +35 -2
- data/lib/mongo/client.rb +38 -6
- data/lib/mongo/client_encryption.rb +6 -3
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +6 -1
- data/lib/mongo/cluster/sdam_flow.rb +20 -7
- data/lib/mongo/cluster/topology/base.rb +16 -0
- data/lib/mongo/cluster.rb +41 -5
- data/lib/mongo/collection/helpers.rb +1 -1
- data/lib/mongo/collection/view/aggregation/behavior.rb +131 -0
- data/lib/mongo/collection/view/aggregation.rb +33 -99
- data/lib/mongo/collection/view/builder/aggregation.rb +1 -7
- data/lib/mongo/collection/view/change_stream.rb +80 -27
- data/lib/mongo/collection/view/iterable.rb +92 -60
- data/lib/mongo/collection/view/map_reduce.rb +25 -8
- data/lib/mongo/collection/view/readable.rb +79 -30
- data/lib/mongo/collection/view/writable.rb +109 -48
- data/lib/mongo/collection/view.rb +44 -3
- data/lib/mongo/collection.rb +185 -26
- data/lib/mongo/config.rb +2 -2
- data/lib/mongo/crypt/auto_encrypter.rb +4 -6
- data/lib/mongo/crypt/binding.rb +4 -4
- data/lib/mongo/crypt/context.rb +20 -14
- data/lib/mongo/crypt/encryption_io.rb +56 -26
- data/lib/mongo/crypt/explicit_encrypter.rb +49 -20
- data/lib/mongo/crypt/explicit_encryption_context.rb +17 -11
- data/lib/mongo/crypt/kms/azure/credentials_retriever.rb +22 -6
- data/lib/mongo/crypt/kms/gcp/credentials_retriever.rb +29 -4
- data/lib/mongo/csot_timeout_holder.rb +119 -0
- data/lib/mongo/cursor/kill_spec.rb +5 -2
- data/lib/mongo/cursor/nontailable.rb +27 -0
- data/lib/mongo/cursor.rb +86 -24
- data/lib/mongo/cursor_host.rb +82 -0
- data/lib/mongo/database/view.rb +81 -14
- data/lib/mongo/database.rb +88 -18
- data/lib/mongo/error/operation_failure.rb +209 -204
- data/lib/mongo/error/server_timeout_error.rb +12 -0
- data/lib/mongo/error/socket_timeout_error.rb +3 -1
- data/lib/mongo/error/timeout_error.rb +23 -0
- data/lib/mongo/error/transactions_not_supported.rb +34 -0
- data/lib/mongo/error.rb +3 -0
- data/lib/mongo/grid/fs_bucket.rb +48 -9
- data/lib/mongo/grid/stream/read.rb +15 -1
- data/lib/mongo/grid/stream/write.rb +21 -4
- data/lib/mongo/index/view.rb +77 -16
- data/lib/mongo/monitoring/event/secure.rb +1 -1
- data/lib/mongo/operation/context.rb +40 -2
- data/lib/mongo/operation/create_search_indexes/op_msg.rb +31 -0
- data/lib/mongo/operation/create_search_indexes.rb +15 -0
- data/lib/mongo/operation/delete/op_msg.rb +2 -1
- data/lib/mongo/operation/drop_search_index/op_msg.rb +33 -0
- data/lib/mongo/operation/drop_search_index.rb +15 -0
- data/lib/mongo/operation/find/op_msg.rb +45 -0
- data/lib/mongo/operation/get_more/op_msg.rb +33 -0
- data/lib/mongo/operation/insert/op_msg.rb +3 -2
- data/lib/mongo/operation/insert/result.rb +4 -2
- data/lib/mongo/operation/list_collections/result.rb +1 -1
- data/lib/mongo/operation/map_reduce/result.rb +1 -1
- data/lib/mongo/operation/op_msg_base.rb +3 -1
- data/lib/mongo/operation/result.rb +26 -5
- data/lib/mongo/operation/shared/executable.rb +55 -28
- data/lib/mongo/operation/shared/op_msg_executable.rb +4 -1
- data/lib/mongo/operation/shared/response_handling.rb +25 -27
- data/lib/mongo/operation/shared/sessions_supported.rb +1 -1
- data/lib/mongo/operation/shared/specifiable.rb +7 -0
- data/lib/mongo/operation/shared/timed.rb +52 -0
- data/lib/mongo/operation/shared/write.rb +4 -1
- data/lib/mongo/operation/update/op_msg.rb +2 -1
- data/lib/mongo/operation/update_search_index/op_msg.rb +34 -0
- data/lib/mongo/operation/update_search_index.rb +15 -0
- data/lib/mongo/operation.rb +4 -0
- data/lib/mongo/protocol/message.rb +1 -4
- data/lib/mongo/protocol/msg.rb +2 -2
- data/lib/mongo/retryable/base_worker.rb +28 -3
- data/lib/mongo/retryable/read_worker.rb +78 -36
- data/lib/mongo/retryable/write_worker.rb +59 -25
- data/lib/mongo/retryable.rb +8 -2
- data/lib/mongo/search_index/view.rb +232 -0
- data/lib/mongo/server/app_metadata/environment.rb +64 -9
- data/lib/mongo/server/app_metadata.rb +5 -4
- data/lib/mongo/server/connection.rb +11 -5
- data/lib/mongo/server/connection_base.rb +22 -2
- data/lib/mongo/server/connection_pool.rb +32 -14
- data/lib/mongo/server/description/features.rb +2 -1
- data/lib/mongo/server/description.rb +18 -5
- data/lib/mongo/server/monitor.rb +7 -4
- data/lib/mongo/server/pending_connection.rb +25 -8
- data/lib/mongo/server/{round_trip_time_averager.rb → round_trip_time_calculator.rb} +25 -7
- data/lib/mongo/server.rb +11 -6
- data/lib/mongo/server_selector/base.rb +54 -12
- data/lib/mongo/session/server_session/dirtyable.rb +52 -0
- data/lib/mongo/session/server_session.rb +3 -0
- data/lib/mongo/session/session_pool.rb +12 -18
- data/lib/mongo/session.rb +110 -9
- data/lib/mongo/socket/ssl.rb +131 -18
- data/lib/mongo/socket/tcp.rb +40 -6
- data/lib/mongo/socket.rb +154 -25
- data/lib/mongo/uri/options_mapper.rb +1 -0
- data/lib/mongo/uri.rb +0 -4
- data/lib/mongo/version.rb +1 -5
- data/lib/mongo.rb +2 -0
- data/mongo.gemspec +9 -18
- data/spec/atlas/atlas_connectivity_spec.rb +9 -9
- data/spec/atlas/operations_spec.rb +5 -5
- data/spec/faas/ruby-sam-app/Gemfile +9 -0
- data/spec/faas/ruby-sam-app/mongodb/Gemfile +4 -0
- data/spec/faas/ruby-sam-app/mongodb/app.rb +149 -0
- data/spec/faas/ruby-sam-app/template.yaml +48 -0
- data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +2 -1
- data/spec/integration/client_side_encryption/auto_encryption_spec.rb +494 -487
- data/spec/integration/client_side_encryption/corpus_spec.rb +10 -2
- data/spec/integration/client_side_encryption/on_demand_aws_credentials_spec.rb +1 -1
- data/spec/integration/client_side_encryption/range_explicit_encryption_prose_spec.rb +67 -20
- data/spec/integration/client_side_operations_timeout/encryption_prose_spec.rb +131 -0
- data/spec/integration/connection_pool_populator_spec.rb +2 -0
- data/spec/integration/cursor_pinning_spec.rb +15 -60
- data/spec/integration/cursor_reaping_spec.rb +1 -1
- data/spec/integration/docs_examples_spec.rb +1 -1
- data/spec/integration/find_options_spec.rb +227 -0
- data/spec/integration/operation_failure_code_spec.rb +1 -1
- data/spec/integration/operation_failure_message_spec.rb +3 -3
- data/spec/integration/retryable_errors_spec.rb +2 -2
- data/spec/integration/retryable_reads_errors_spec.rb +196 -31
- data/spec/integration/retryable_writes_errors_spec.rb +156 -0
- data/spec/integration/sdam_error_handling_spec.rb +4 -1
- data/spec/integration/search_indexes_prose_spec.rb +172 -0
- data/spec/integration/server_spec.rb +4 -3
- data/spec/integration/transactions_api_examples_spec.rb +2 -0
- data/spec/kerberos/kerberos_spec.rb +4 -0
- data/spec/lite_spec_helper.rb +34 -20
- data/spec/mongo/auth/user/view_spec.rb +1 -1
- data/spec/mongo/caching_cursor_spec.rb +1 -1
- data/spec/mongo/client_encryption_spec.rb +1 -0
- data/spec/mongo/client_spec.rb +158 -4
- data/spec/mongo/cluster_spec.rb +36 -0
- data/spec/mongo/collection/view/aggregation_spec.rb +20 -40
- data/spec/mongo/collection/view/change_stream_spec.rb +3 -3
- data/spec/mongo/collection/view/explainable_spec.rb +2 -0
- data/spec/mongo/collection_crud_spec.rb +2 -1
- data/spec/mongo/collection_spec.rb +5 -6
- data/spec/mongo/crypt/auto_encrypter_spec.rb +14 -12
- data/spec/mongo/crypt/data_key_context_spec.rb +3 -1
- data/spec/mongo/crypt/explicit_encryption_context_spec.rb +2 -2
- data/spec/mongo/crypt/handle_spec.rb +1 -1
- data/spec/mongo/cursor_spec.rb +26 -9
- data/spec/mongo/error/operation_failure_heavy_spec.rb +2 -2
- data/spec/mongo/operation/context_spec.rb +79 -0
- data/spec/mongo/operation/create/op_msg_spec.rb +106 -110
- data/spec/mongo/operation/delete/op_msg_spec.rb +6 -5
- data/spec/mongo/operation/find/op_msg_spec.rb +66 -0
- data/spec/mongo/operation/get_more/op_msg_spec.rb +65 -0
- data/spec/mongo/operation/insert/op_msg_spec.rb +128 -131
- data/spec/mongo/operation/insert_spec.rb +1 -1
- data/spec/mongo/operation/shared/csot/examples.rb +113 -0
- data/spec/mongo/query_cache_spec.rb +243 -225
- data/spec/mongo/retryable/write_worker_spec.rb +39 -0
- data/spec/mongo/retryable_spec.rb +1 -0
- data/spec/mongo/server/app_metadata/environment_spec.rb +135 -0
- data/spec/mongo/server/app_metadata_spec.rb +12 -2
- data/spec/mongo/server/connection_spec.rb +26 -0
- data/spec/mongo/server/round_trip_time_calculator_spec.rb +120 -0
- data/spec/mongo/session/session_pool_spec.rb +1 -16
- data/spec/mongo/session_transaction_spec.rb +15 -0
- data/spec/mongo/socket/ssl_spec.rb +0 -10
- data/spec/mongo/uri_spec.rb +0 -9
- data/spec/runners/change_streams/test.rb +2 -2
- data/spec/runners/crud/operation.rb +1 -1
- data/spec/runners/crud/test.rb +0 -8
- data/spec/runners/crud/verifier.rb +3 -1
- data/spec/runners/crud.rb +1 -1
- data/spec/runners/transactions/operation.rb +4 -6
- data/spec/runners/transactions/test.rb +12 -3
- data/spec/runners/unified/ambiguous_operations.rb +13 -0
- data/spec/runners/unified/assertions.rb +20 -3
- data/spec/runners/unified/change_stream_operations.rb +14 -24
- data/spec/runners/unified/crud_operations.rb +82 -47
- data/spec/runners/unified/ddl_operations.rb +38 -7
- data/spec/runners/unified/grid_fs_operations.rb +37 -2
- data/spec/runners/unified/search_index_operations.rb +63 -0
- data/spec/runners/unified/support_operations.rb +46 -9
- data/spec/runners/unified/test.rb +33 -12
- data/spec/runners/unified.rb +1 -1
- data/spec/solo/clean_exit_spec.rb +2 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/spec_tests/client_side_operations_timeout_spec.rb +15 -0
- data/spec/spec_tests/data/change_streams_unified/change-streams-clusterTime.yml +3 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-disambiguatedPaths.yml +3 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-errors.yml +3 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-pre_and_post_images.yml +1 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-resume-allowlist.yml +1 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-resume-errorLabels.yml +1 -1
- data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +1 -1
- data/spec/spec_tests/data/client_side_encryption/badQueries.yml +2 -1
- data/spec/spec_tests/data/client_side_encryption/explain.yml +2 -2
- data/spec/spec_tests/data/client_side_encryption/fle2v2-BypassQueryAnalysis.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Compact.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-CreateCollection.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-DecryptExistingData.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Delete.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFields-vs-EncryptedFieldsMap.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFields-vs-jsonSchema.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFieldsMap-defaults.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-FindOneAndUpdate.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-InsertFind-Indexed.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-InsertFind-Unindexed.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-MissingKey.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-NoEncryption.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Update.yml +1 -0
- data/spec/spec_tests/data/client_side_encryption/fle2v2-validatorAndPartialFieldExpression.yml +2 -1
- data/spec/spec_tests/data/client_side_encryption/timeoutMS.yml +67 -0
- data/spec/spec_tests/data/client_side_operations_timeout/bulkWrite.yml +87 -0
- data/spec/spec_tests/data/client_side_operations_timeout/change-streams.yml +358 -0
- data/spec/spec_tests/data/client_side_operations_timeout/close-cursors.yml +129 -0
- data/spec/spec_tests/data/client_side_operations_timeout/command-execution.yml +250 -0
- data/spec/spec_tests/data/client_side_operations_timeout/convenient-transactions.yml +113 -0
- data/spec/spec_tests/data/client_side_operations_timeout/cursors.yml +70 -0
- data/spec/spec_tests/data/client_side_operations_timeout/deprecated-options.yml +3982 -0
- data/spec/spec_tests/data/client_side_operations_timeout/error-transformations.yml +96 -0
- data/spec/spec_tests/data/client_side_operations_timeout/global-timeoutMS.yml +3236 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-advanced.yml +207 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-delete.yml +152 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-download.yml +182 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-find.yml +100 -0
- data/spec/spec_tests/data/client_side_operations_timeout/gridfs-upload.yml +249 -0
- data/spec/spec_tests/data/client_side_operations_timeout/legacy-timeouts.yml +204 -0
- data/spec/spec_tests/data/client_side_operations_timeout/non-tailable-cursors.yml +307 -0
- data/spec/spec_tests/data/client_side_operations_timeout/override-collection-timeoutMS.yml +1877 -0
- data/spec/spec_tests/data/client_side_operations_timeout/override-operation-timeoutMS.yml +1918 -0
- data/spec/spec_tests/data/client_side_operations_timeout/retryability-legacy-timeouts.yml +1676 -0
- data/spec/spec_tests/data/client_side_operations_timeout/retryability-timeoutMS.yml +2824 -0
- data/spec/spec_tests/data/client_side_operations_timeout/sessions-inherit-timeoutMS.yml +168 -0
- data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-operation-timeoutMS.yml +171 -0
- data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-timeoutMS.yml +168 -0
- data/spec/spec_tests/data/client_side_operations_timeout/tailable-awaitData.yml +247 -0
- data/spec/spec_tests/data/client_side_operations_timeout/tailable-non-awaitData.yml +181 -0
- data/spec/spec_tests/data/connection_string/invalid-uris.yml +0 -10
- data/spec/spec_tests/data/connection_string/valid-options.yml +13 -0
- data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +6 -0
- data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +6 -0
- data/spec/spec_tests/data/crud_unified/find-test-all-options.yml +377 -0
- data/spec/spec_tests/data/index_management/createSearchIndex.yml +64 -0
- data/spec/spec_tests/data/index_management/createSearchIndexes.yml +86 -0
- data/spec/spec_tests/data/index_management/dropSearchIndex.yml +43 -0
- data/spec/spec_tests/data/index_management/listSearchIndexes.yml +91 -0
- data/spec/spec_tests/data/index_management/updateSearchIndex.yml +46 -0
- data/spec/spec_tests/data/retryable_writes/unified/bulkWrite-serverErrors.yml +3 -6
- data/spec/spec_tests/data/retryable_writes/unified/insertOne-serverErrors.yml +3 -6
- data/spec/spec_tests/data/run_command_unified/runCommand.yml +319 -0
- data/spec/spec_tests/data/sessions_unified/driver-sessions-dirty-session-errors.yml +351 -0
- data/spec/spec_tests/data/unified/valid-pass/poc-crud.yml +1 -1
- data/spec/spec_tests/data/unified/valid-pass/poc-retryable-writes.yml +7 -7
- data/spec/spec_tests/data/unified/valid-pass/poc-sessions.yml +3 -4
- data/spec/spec_tests/data/unified/valid-pass/poc-transactions-convenient-api.yml +1 -1
- data/spec/spec_tests/data/unified/valid-pass/poc-transactions-mongos-pin-auto.yml +1 -1
- data/spec/spec_tests/data/unified/valid-pass/poc-transactions.yml +3 -3
- data/spec/spec_tests/index_management_unified_spec.rb +13 -0
- data/spec/spec_tests/run_command_unified_spec.rb +13 -0
- data/spec/spec_tests/sdam_unified_spec.rb +2 -0
- data/spec/spec_tests/server_selection_rtt_spec.rb +6 -6
- data/spec/spec_tests/transactions_unified_spec.rb +2 -1
- data/spec/support/certificates/atlas-ocsp-ca.crt +89 -79
- data/spec/support/certificates/atlas-ocsp.crt +117 -122
- data/spec/support/certificates/retrieve-atlas-cert +1 -1
- data/spec/support/cluster_tools.rb +3 -3
- data/spec/support/common_shortcuts.rb +2 -2
- data/spec/support/constraints.rb +6 -0
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-Date.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalNoPrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalPrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoubleNoPrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoublePrecision.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-Int.json +1 -1
- data/spec/support/crypt/encrypted_fields/range-encryptedFields-Long.json +1 -1
- data/spec/support/ocsp +1 -1
- data/spec/support/recording_logger.rb +27 -0
- data/spec/support/shared/session.rb +2 -2
- data/spec/support/spec_config.rb +5 -0
- data/spec/support/spec_setup.rb +2 -2
- data/spec/support/utils.rb +3 -1
- metadata +1329 -1368
- checksums.yaml.gz.sig +0 -0
- data/spec/mongo/server/round_trip_time_averager_spec.rb +0 -48
- data/spec/shared/LICENSE +0 -20
- data/spec/shared/bin/get-mongodb-download-url +0 -17
- data/spec/shared/bin/s3-copy +0 -45
- data/spec/shared/bin/s3-upload +0 -69
- data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
- data/spec/shared/lib/mrss/cluster_config.rb +0 -231
- data/spec/shared/lib/mrss/constraints.rb +0 -378
- data/spec/shared/lib/mrss/docker_runner.rb +0 -295
- data/spec/shared/lib/mrss/eg_config_utils.rb +0 -51
- data/spec/shared/lib/mrss/event_subscriber.rb +0 -210
- data/spec/shared/lib/mrss/lite_constraints.rb +0 -238
- data/spec/shared/lib/mrss/server_version_registry.rb +0 -113
- data/spec/shared/lib/mrss/session_registry.rb +0 -69
- data/spec/shared/lib/mrss/session_registry_legacy.rb +0 -60
- data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
- data/spec/shared/lib/mrss/utils.rb +0 -37
- data/spec/shared/share/Dockerfile.erb +0 -330
- data/spec/shared/share/haproxy-1.conf +0 -16
- data/spec/shared/share/haproxy-2.conf +0 -17
- data/spec/shared/shlib/config.sh +0 -27
- data/spec/shared/shlib/distro.sh +0 -74
- data/spec/shared/shlib/server.sh +0 -416
- data/spec/shared/shlib/set_env.sh +0 -169
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Aggregate.yml +0 -241
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Correctness.yml +0 -422
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Delete.yml +0 -182
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-FindOneAndUpdate.yml +0 -239
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-InsertFind.yml +0 -235
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Update.yml +0 -252
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Aggregate.yml +0 -1687
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Correctness.yml +0 -293
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Delete.yml +0 -905
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-FindOneAndUpdate.yml +0 -1684
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-InsertFind.yml +0 -1680
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Update.yml +0 -1697
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Aggregate.yml +0 -329
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Correctness.yml +0 -424
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Delete.yml +0 -226
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-FindOneAndUpdate.yml +0 -327
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-InsertFind.yml +0 -319
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Update.yml +0 -336
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Aggregate.yml +0 -913
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Correctness.yml +0 -292
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Delete.yml +0 -518
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-FindOneAndUpdate.yml +0 -911
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-InsertFind.yml +0 -907
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Update.yml +0 -924
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Aggregate.yml +0 -325
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Correctness.yml +0 -424
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Delete.yml +0 -224
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-FindOneAndUpdate.yml +0 -323
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-InsertFind.yml +0 -319
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Update.yml +0 -338
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Aggregate.yml +0 -241
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Correctness.yml +0 -423
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Delete.yml +0 -182
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-FindOneAndUpdate.yml +0 -239
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-InsertFind.yml +0 -235
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Update.yml +0 -254
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Aggregate.yml +0 -241
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Correctness.yml +0 -422
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Delete.yml +0 -182
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-FindOneAndUpdate.yml +0 -239
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-InsertFind.yml +0 -235
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Update.yml +0 -254
- data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-WrongType.yml +0 -43
- data/spec/spec_tests/data/cmap/pool-clear-interrupt-immediately.yml +0 -49
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -2
|
@@ -60,19 +60,21 @@ module Mongo
|
|
|
60
60
|
# @param [ Mongo::ServerSelector::Selectable ] server_selector Server
|
|
61
61
|
# selector for the operation.
|
|
62
62
|
# @param [ CollectionView ] view The +CollectionView+ defining the query.
|
|
63
|
+
# @param [ Operation::Context | nil ] context the operation context to use
|
|
64
|
+
# with the cursor.
|
|
63
65
|
# @param [ Proc ] block The block to execute.
|
|
64
66
|
#
|
|
65
67
|
# @return [ Cursor ] The cursor for the result set.
|
|
66
|
-
def read_with_retry_cursor(session, server_selector, view, &block)
|
|
67
|
-
read_with_retry(session, server_selector) do |server|
|
|
68
|
+
def read_with_retry_cursor(session, server_selector, view, context: nil, &block)
|
|
69
|
+
read_with_retry(session, server_selector, context) do |server|
|
|
68
70
|
result = yield server
|
|
69
71
|
|
|
70
72
|
# RUBY-2367: This will be updated to allow the query cache to
|
|
71
73
|
# cache cursors with multi-batch results.
|
|
72
74
|
if QueryCache.enabled? && !view.collection.system_collection?
|
|
73
|
-
CachingCursor.new(view, result, server, session: session)
|
|
75
|
+
CachingCursor.new(view, result, server, session: session, context: context)
|
|
74
76
|
else
|
|
75
|
-
Cursor.new(view, result, server, session: session)
|
|
77
|
+
Cursor.new(view, result, server, session: session, context: context)
|
|
76
78
|
end
|
|
77
79
|
end
|
|
78
80
|
end
|
|
@@ -107,16 +109,18 @@ module Mongo
|
|
|
107
109
|
# is being run on.
|
|
108
110
|
# @param [ Mongo::ServerSelector::Selectable | nil ] server_selector
|
|
109
111
|
# Server selector for the operation.
|
|
112
|
+
# @param [ Mongo::Operation::Context | nil ] context Context for the
|
|
113
|
+
# read operation.
|
|
110
114
|
# @param [ Proc ] block The block to execute.
|
|
111
115
|
#
|
|
112
116
|
# @return [ Result ] The result of the operation.
|
|
113
|
-
def read_with_retry(session = nil, server_selector = nil, &block)
|
|
117
|
+
def read_with_retry(session = nil, server_selector = nil, context = nil, &block)
|
|
114
118
|
if session.nil? && server_selector.nil?
|
|
115
119
|
deprecated_legacy_read_with_retry(&block)
|
|
116
120
|
elsif session&.retry_reads?
|
|
117
|
-
modern_read_with_retry(session, server_selector, &block)
|
|
121
|
+
modern_read_with_retry(session, server_selector, context, &block)
|
|
118
122
|
elsif client.max_read_retries > 0
|
|
119
|
-
legacy_read_with_retry(session, server_selector, &block)
|
|
123
|
+
legacy_read_with_retry(session, server_selector, context, &block)
|
|
120
124
|
else
|
|
121
125
|
read_without_retry(session, server_selector, &block)
|
|
122
126
|
end
|
|
@@ -186,18 +190,26 @@ module Mongo
|
|
|
186
190
|
# being run on.
|
|
187
191
|
# @param [ Mongo::ServerSelector::Selectable ] server_selector Server
|
|
188
192
|
# selector for the operation.
|
|
193
|
+
# @param [ Mongo::Operation::Context ] context Context for the
|
|
194
|
+
# read operation.
|
|
189
195
|
# @param [ Proc ] block The block to execute.
|
|
190
196
|
#
|
|
191
197
|
# @return [ Result ] The result of the operation.
|
|
192
|
-
def modern_read_with_retry(session, server_selector, &block)
|
|
193
|
-
|
|
194
|
-
|
|
198
|
+
def modern_read_with_retry(session, server_selector, context, &block)
|
|
199
|
+
server = select_server(
|
|
200
|
+
cluster,
|
|
201
|
+
server_selector,
|
|
202
|
+
session,
|
|
203
|
+
timeout: context&.remaining_timeout_sec
|
|
204
|
+
)
|
|
205
|
+
yield server
|
|
206
|
+
rescue *retryable_exceptions, Error::OperationFailure::Family, Auth::Unauthorized, Error::PoolError => e
|
|
195
207
|
e.add_notes('modern retry', 'attempt 1')
|
|
196
208
|
raise e if session.in_transaction?
|
|
197
209
|
raise e if !is_retryable_exception?(e) && !e.write_retryable?
|
|
198
|
-
retry_read(e, session, server_selector, &block)
|
|
210
|
+
retry_read(e, session, server_selector, context: context, failed_server: server, &block)
|
|
199
211
|
end
|
|
200
|
-
|
|
212
|
+
|
|
201
213
|
# Attempts to do a "legacy" read with retry. The operation will be
|
|
202
214
|
# attempted multiple times, up to the client's `max_read_retries`
|
|
203
215
|
# setting.
|
|
@@ -206,23 +218,26 @@ module Mongo
|
|
|
206
218
|
# being run on.
|
|
207
219
|
# @param [ Mongo::ServerSelector::Selectable ] server_selector Server
|
|
208
220
|
# selector for the operation.
|
|
221
|
+
# @param [ Mongo::Operation::Context | nil ] context Context for the
|
|
222
|
+
# read operation.
|
|
209
223
|
# @param [ Proc ] block The block to execute.
|
|
210
224
|
#
|
|
211
225
|
# @return [ Result ] The result of the operation.
|
|
212
|
-
def legacy_read_with_retry(session, server_selector, &block)
|
|
226
|
+
def legacy_read_with_retry(session, server_selector, context = nil, &block)
|
|
227
|
+
context&.check_timeout!
|
|
213
228
|
attempt = attempt ? attempt + 1 : 1
|
|
214
229
|
yield select_server(cluster, server_selector, session)
|
|
215
|
-
rescue *
|
|
230
|
+
rescue *legacy_retryable_exceptions, Error::OperationFailure::Family => e
|
|
216
231
|
e.add_notes('legacy retry', "attempt #{attempt}")
|
|
217
|
-
|
|
218
|
-
if
|
|
232
|
+
|
|
233
|
+
if is_legacy_retryable_exception?(e)
|
|
219
234
|
raise e if attempt > client.max_read_retries || session&.in_transaction?
|
|
220
235
|
elsif e.retryable? && !session&.in_transaction?
|
|
221
236
|
raise e if attempt > client.max_read_retries
|
|
222
237
|
else
|
|
223
238
|
raise e
|
|
224
239
|
end
|
|
225
|
-
|
|
240
|
+
|
|
226
241
|
log_retry(e, message: 'Legacy read retry')
|
|
227
242
|
sleep(client.read_retry_interval) unless is_retryable_exception?(e)
|
|
228
243
|
retry
|
|
@@ -243,7 +258,7 @@ module Mongo
|
|
|
243
258
|
|
|
244
259
|
begin
|
|
245
260
|
yield server
|
|
246
|
-
rescue *retryable_exceptions, Error::PoolError, Error::OperationFailure => e
|
|
261
|
+
rescue *retryable_exceptions, Error::PoolError, Error::OperationFailure::Family => e
|
|
247
262
|
e.add_note('retries disabled')
|
|
248
263
|
raise e
|
|
249
264
|
end
|
|
@@ -257,40 +272,67 @@ module Mongo
|
|
|
257
272
|
# being run on.
|
|
258
273
|
# @param [ Mongo::ServerSelector::Selectable ] server_selector Server
|
|
259
274
|
# selector for the operation.
|
|
275
|
+
# @param [ Mongo::Operation::Context | nil ] :context Context for the
|
|
276
|
+
# read operation.
|
|
277
|
+
# @param [ Mongo::Server | nil ] :failed_server The server on which the original
|
|
278
|
+
# operation failed.
|
|
260
279
|
# @param [ Proc ] block The block to execute.
|
|
261
|
-
#
|
|
280
|
+
#
|
|
262
281
|
# @return [ Result ] The result of the operation.
|
|
263
|
-
def retry_read(original_error, session, server_selector, &block)
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
raise original_error
|
|
269
|
-
end
|
|
270
|
-
|
|
282
|
+
def retry_read(original_error, session, server_selector, context: nil, failed_server: nil, &block)
|
|
283
|
+
server = select_server_for_retry(
|
|
284
|
+
original_error, session, server_selector, context, failed_server
|
|
285
|
+
)
|
|
286
|
+
|
|
271
287
|
log_retry(original_error, message: 'Read retry')
|
|
272
|
-
|
|
288
|
+
|
|
273
289
|
begin
|
|
290
|
+
context&.check_timeout!
|
|
291
|
+
attempt = attempt ? attempt + 1 : 2
|
|
274
292
|
yield server, true
|
|
293
|
+
rescue Error::TimeoutError
|
|
294
|
+
raise
|
|
275
295
|
rescue *retryable_exceptions => e
|
|
276
|
-
e.add_notes('modern retry',
|
|
277
|
-
|
|
278
|
-
|
|
296
|
+
e.add_notes('modern retry', "attempt #{attempt}")
|
|
297
|
+
if context&.csot?
|
|
298
|
+
failed_server = server
|
|
299
|
+
retry
|
|
300
|
+
else
|
|
301
|
+
raise e
|
|
302
|
+
end
|
|
303
|
+
rescue Error::OperationFailure::Family, Error::PoolError => e
|
|
279
304
|
e.add_note('modern retry')
|
|
280
|
-
|
|
305
|
+
if e.write_retryable?
|
|
306
|
+
e.add_note("attempt #{attempt}")
|
|
307
|
+
if context&.csot?
|
|
308
|
+
failed_server = server
|
|
309
|
+
retry
|
|
310
|
+
else
|
|
311
|
+
raise e
|
|
312
|
+
end
|
|
313
|
+
else
|
|
281
314
|
original_error.add_note("later retry failed: #{e.class}: #{e}")
|
|
282
315
|
raise original_error
|
|
283
316
|
end
|
|
284
|
-
e.add_note("attempt 2")
|
|
285
|
-
raise e
|
|
286
317
|
rescue Error, Error::AuthError => e
|
|
287
318
|
e.add_note('modern retry')
|
|
288
319
|
original_error.add_note("later retry failed: #{e.class}: #{e}")
|
|
289
320
|
raise original_error
|
|
290
321
|
end
|
|
291
322
|
end
|
|
292
|
-
|
|
293
|
-
end
|
|
294
323
|
|
|
324
|
+
def select_server_for_retry(original_error, session, server_selector, context, failed_server)
|
|
325
|
+
select_server(
|
|
326
|
+
cluster,
|
|
327
|
+
server_selector,
|
|
328
|
+
session,
|
|
329
|
+
failed_server,
|
|
330
|
+
timeout: context&.remaining_timeout_sec
|
|
331
|
+
)
|
|
332
|
+
rescue Error, Error::AuthError => e
|
|
333
|
+
original_error.add_note("later retry failed: #{e.class}: #{e}")
|
|
334
|
+
raise original_error
|
|
335
|
+
end
|
|
336
|
+
end
|
|
295
337
|
end
|
|
296
338
|
end
|
|
@@ -74,7 +74,11 @@ module Mongo
|
|
|
74
74
|
# If we are here, session is not nil. A session being nil would have
|
|
75
75
|
# failed retry_write_allowed? check.
|
|
76
76
|
|
|
77
|
-
server = select_server(
|
|
77
|
+
server = select_server(
|
|
78
|
+
cluster, ServerSelector.primary,
|
|
79
|
+
session,
|
|
80
|
+
timeout: context.remaining_timeout_sec
|
|
81
|
+
)
|
|
78
82
|
|
|
79
83
|
unless ending_transaction || server.retry_writes?
|
|
80
84
|
return legacy_write_with_retry(server, context: context, &block)
|
|
@@ -103,13 +107,14 @@ module Mongo
|
|
|
103
107
|
def nro_write_with_retry(write_concern, context:, &block)
|
|
104
108
|
session = context.session
|
|
105
109
|
server = select_server(cluster, ServerSelector.primary, session)
|
|
106
|
-
|
|
107
|
-
|
|
110
|
+
options = session&.client&.options || {}
|
|
111
|
+
|
|
112
|
+
if options[:retry_writes]
|
|
108
113
|
begin
|
|
109
114
|
server.with_connection(connection_global_id: context.connection_global_id) do |connection|
|
|
110
115
|
yield connection, nil, context
|
|
111
116
|
end
|
|
112
|
-
rescue *retryable_exceptions, Error::PoolError, Error::OperationFailure => e
|
|
117
|
+
rescue *retryable_exceptions, Error::PoolError, Error::OperationFailure::Family => e
|
|
113
118
|
e.add_note('retries disabled')
|
|
114
119
|
raise e
|
|
115
120
|
end
|
|
@@ -169,6 +174,7 @@ module Mongo
|
|
|
169
174
|
# @api private
|
|
170
175
|
def legacy_write_with_retry(server = nil, context:)
|
|
171
176
|
session = context.session
|
|
177
|
+
context.check_timeout!
|
|
172
178
|
|
|
173
179
|
# This is the pre-session retry logic, and is not subject to
|
|
174
180
|
# current retryable write specifications.
|
|
@@ -176,12 +182,20 @@ module Mongo
|
|
|
176
182
|
attempt = 0
|
|
177
183
|
begin
|
|
178
184
|
attempt += 1
|
|
179
|
-
server ||= select_server(
|
|
180
|
-
|
|
185
|
+
server ||= select_server(
|
|
186
|
+
cluster,
|
|
187
|
+
ServerSelector.primary,
|
|
188
|
+
session,
|
|
189
|
+
timeout: context.remaining_timeout_sec
|
|
190
|
+
)
|
|
191
|
+
server.with_connection(
|
|
192
|
+
connection_global_id: context.connection_global_id,
|
|
193
|
+
context: context
|
|
194
|
+
) do |connection|
|
|
181
195
|
# Legacy retries do not use txn_num
|
|
182
196
|
yield connection, nil, context.dup
|
|
183
197
|
end
|
|
184
|
-
rescue Error::OperationFailure => e
|
|
198
|
+
rescue Error::OperationFailure::Family => e
|
|
185
199
|
e.add_note('legacy retry')
|
|
186
200
|
e.add_note("attempt #{attempt}")
|
|
187
201
|
server = nil
|
|
@@ -218,8 +232,11 @@ module Mongo
|
|
|
218
232
|
def modern_write_with_retry(session, server, context, &block)
|
|
219
233
|
txn_num = nil
|
|
220
234
|
connection_succeeded = false
|
|
221
|
-
|
|
222
|
-
server.with_connection(
|
|
235
|
+
|
|
236
|
+
server.with_connection(
|
|
237
|
+
connection_global_id: context.connection_global_id,
|
|
238
|
+
context: context
|
|
239
|
+
) do |connection|
|
|
223
240
|
connection_succeeded = true
|
|
224
241
|
|
|
225
242
|
session.materialize_if_needed
|
|
@@ -229,10 +246,10 @@ module Mongo
|
|
|
229
246
|
# it later for the retry as well.
|
|
230
247
|
yield connection, txn_num, context.dup
|
|
231
248
|
end
|
|
232
|
-
rescue *retryable_exceptions, Error::PoolError, Auth::Unauthorized, Error::OperationFailure => e
|
|
249
|
+
rescue *retryable_exceptions, Error::PoolError, Auth::Unauthorized, Error::OperationFailure::Family => e
|
|
233
250
|
e.add_notes('modern retry', 'attempt 1')
|
|
234
251
|
|
|
235
|
-
if e.is_a?(Error::OperationFailure)
|
|
252
|
+
if e.is_a?(Error::OperationFailure::Family)
|
|
236
253
|
ensure_retryable!(e)
|
|
237
254
|
else
|
|
238
255
|
ensure_labeled_retryable!(e, connection_succeeded, session)
|
|
@@ -240,7 +257,7 @@ module Mongo
|
|
|
240
257
|
|
|
241
258
|
# Context#with creates a new context, which is not necessary here
|
|
242
259
|
# but the API is less prone to misuse this way.
|
|
243
|
-
retry_write(e, txn_num, context: context.with(is_retry: true), &block)
|
|
260
|
+
retry_write(e, txn_num, context: context.with(is_retry: true), failed_server: server, &block)
|
|
244
261
|
end
|
|
245
262
|
|
|
246
263
|
# Called after a failed write, this will retry the write no more than
|
|
@@ -250,9 +267,13 @@ module Mongo
|
|
|
250
267
|
# retry.
|
|
251
268
|
# @param [ Number ] txn_num The transaction number.
|
|
252
269
|
# @param [ Operation::Context ] context The context for the operation.
|
|
270
|
+
# @param [ Mongo::Server ] failed_server The server on which the original
|
|
271
|
+
# operation failed.
|
|
253
272
|
#
|
|
254
273
|
# @return [ Result ] The result of the operation.
|
|
255
|
-
def retry_write(original_error, txn_num, context:, &block)
|
|
274
|
+
def retry_write(original_error, txn_num, context:, failed_server: nil, &block)
|
|
275
|
+
context&.check_timeout!
|
|
276
|
+
|
|
256
277
|
session = context.session
|
|
257
278
|
|
|
258
279
|
# We do not request a scan of the cluster here, because error handling
|
|
@@ -260,8 +281,14 @@ module Mongo
|
|
|
260
281
|
# server description and/or topology as necessary (specifically,
|
|
261
282
|
# a socket error or a not master error should have marked the respective
|
|
262
283
|
# server unknown). Here we just need to wait for server selection.
|
|
263
|
-
server = select_server(
|
|
264
|
-
|
|
284
|
+
server = select_server(
|
|
285
|
+
cluster,
|
|
286
|
+
ServerSelector.primary,
|
|
287
|
+
session,
|
|
288
|
+
failed_server,
|
|
289
|
+
timeout: context.remaining_timeout_sec
|
|
290
|
+
)
|
|
291
|
+
|
|
265
292
|
unless server.retry_writes?
|
|
266
293
|
# Do not need to add "modern retry" here, it should already be on
|
|
267
294
|
# the first exception.
|
|
@@ -275,15 +302,22 @@ module Mongo
|
|
|
275
302
|
# special marker class to bypass the ordinarily applicable rescues.
|
|
276
303
|
raise Error::RaiseOriginalError
|
|
277
304
|
end
|
|
278
|
-
|
|
305
|
+
|
|
306
|
+
attempt = attempt ? attempt + 1 : 2
|
|
279
307
|
log_retry(original_error, message: 'Write retry')
|
|
280
308
|
server.with_connection(connection_global_id: context.connection_global_id) do |connection|
|
|
281
309
|
yield(connection, txn_num, context)
|
|
282
310
|
end
|
|
283
311
|
rescue *retryable_exceptions, Error::PoolError => e
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
312
|
+
maybe_fail_on_retryable(e, original_error, context, attempt)
|
|
313
|
+
failed_server = server
|
|
314
|
+
retry
|
|
315
|
+
rescue Error::OperationFailure::Family => e
|
|
316
|
+
maybe_fail_on_operation_failure(e, original_error, context, attempt)
|
|
317
|
+
failed_server = server
|
|
318
|
+
retry
|
|
319
|
+
rescue Mongo::Error::TimeoutError
|
|
320
|
+
raise
|
|
287
321
|
rescue Error, Error::AuthError => e
|
|
288
322
|
fail_on_other_error!(e, original_error)
|
|
289
323
|
rescue Error::RaiseOriginalError
|
|
@@ -329,10 +363,10 @@ module Mongo
|
|
|
329
363
|
|
|
330
364
|
# Raise either e, or original_error, depending on whether e is
|
|
331
365
|
# write_retryable.
|
|
332
|
-
def
|
|
366
|
+
def maybe_fail_on_retryable(e, original_error, context, attempt)
|
|
333
367
|
if e.write_retryable?
|
|
334
|
-
e.add_notes('modern retry',
|
|
335
|
-
raise e
|
|
368
|
+
e.add_notes('modern retry', "attempt #{attempt}")
|
|
369
|
+
raise e unless context&.deadline
|
|
336
370
|
else
|
|
337
371
|
original_error.add_note("later retry failed: #{e.class}: #{e}")
|
|
338
372
|
raise original_error
|
|
@@ -341,11 +375,11 @@ module Mongo
|
|
|
341
375
|
|
|
342
376
|
# Raise either e, or original_error, depending on whether e is
|
|
343
377
|
# appropriately labeled.
|
|
344
|
-
def
|
|
378
|
+
def maybe_fail_on_operation_failure(e, original_error, context, attempt)
|
|
345
379
|
e.add_note('modern retry')
|
|
346
380
|
if e.label?('RetryableWriteError') && !e.label?('NoWritesPerformed')
|
|
347
|
-
e.add_note(
|
|
348
|
-
raise e
|
|
381
|
+
e.add_note("attempt #{attempt}")
|
|
382
|
+
raise e unless context&.deadline
|
|
349
383
|
else
|
|
350
384
|
original_error.add_note("later retry failed: #{e.class}: #{e}")
|
|
351
385
|
raise original_error
|
data/lib/mongo/retryable.rb
CHANGED
|
@@ -46,8 +46,14 @@ 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)
|
|
50
|
-
server_selector.select_server(
|
|
49
|
+
def select_server(cluster, server_selector, session, failed_server = nil, timeout: nil)
|
|
50
|
+
server_selector.select_server(
|
|
51
|
+
cluster,
|
|
52
|
+
nil,
|
|
53
|
+
session,
|
|
54
|
+
deprioritized: [failed_server].compact,
|
|
55
|
+
timeout: timeout
|
|
56
|
+
)
|
|
51
57
|
end
|
|
52
58
|
|
|
53
59
|
# Returns the read worker for handling retryable reads.
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mongo
|
|
4
|
+
module SearchIndex
|
|
5
|
+
# A class representing a view of search indexes.
|
|
6
|
+
class View
|
|
7
|
+
include Enumerable
|
|
8
|
+
include Retryable
|
|
9
|
+
include Collection::Helpers
|
|
10
|
+
|
|
11
|
+
# @return [ Mongo::Collection ] the collection this view belongs to
|
|
12
|
+
attr_reader :collection
|
|
13
|
+
|
|
14
|
+
# @return [ nil | String ] the index id to query
|
|
15
|
+
attr_reader :requested_index_id
|
|
16
|
+
|
|
17
|
+
# @return [ nil | String ] the index name to query
|
|
18
|
+
attr_reader :requested_index_name
|
|
19
|
+
|
|
20
|
+
# @return [ Hash ] the options hash to use for the aggregate command
|
|
21
|
+
# when querying the available indexes.
|
|
22
|
+
attr_reader :aggregate_options
|
|
23
|
+
|
|
24
|
+
# Create the new search index view.
|
|
25
|
+
#
|
|
26
|
+
# @param [ Collection ] collection The collection.
|
|
27
|
+
# @param [ Hash ] options The options that configure the behavior of the view.
|
|
28
|
+
#
|
|
29
|
+
# @option options [ String ] :id The specific index id to query (optional)
|
|
30
|
+
# @option options [ String ] :name The name of the specific index to query (optional)
|
|
31
|
+
# @option options [ Hash ] :aggregate The options hash to send to the
|
|
32
|
+
# aggregate command when querying the available indexes.
|
|
33
|
+
def initialize(collection, options = {})
|
|
34
|
+
@collection = collection
|
|
35
|
+
@requested_index_id = options[:id]
|
|
36
|
+
@requested_index_name = options[:name]
|
|
37
|
+
@aggregate_options = options[:aggregate] || {}
|
|
38
|
+
|
|
39
|
+
return if @aggregate_options.is_a?(Hash)
|
|
40
|
+
|
|
41
|
+
raise ArgumentError, "The :aggregate option must be a Hash (got a #{@aggregate_options.class})"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Create a single search index with the given definition. If the name is
|
|
45
|
+
# provided, the new index will be given that name.
|
|
46
|
+
#
|
|
47
|
+
# @param [ Hash ] definition The definition of the search index.
|
|
48
|
+
# @param [ nil | String ] name The name to give the new search index.
|
|
49
|
+
#
|
|
50
|
+
# @return [ String ] the name of the new search index.
|
|
51
|
+
def create_one(definition, name: nil)
|
|
52
|
+
create_many([ { name: name, definition: definition } ]).first
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Create multiple search indexes with a single command.
|
|
56
|
+
#
|
|
57
|
+
# @param [ Array<Hash> ] indexes The description of the indexes to
|
|
58
|
+
# create. Each element of the list must be a hash with a definition
|
|
59
|
+
# key, and an optional name key.
|
|
60
|
+
#
|
|
61
|
+
# @return [ Array<String> ] the names of the new search indexes.
|
|
62
|
+
def create_many(indexes)
|
|
63
|
+
spec = spec_with(indexes: indexes.map { |v| validate_search_index!(v) })
|
|
64
|
+
result = Operation::CreateSearchIndexes.new(spec).execute(next_primary, context: execution_context)
|
|
65
|
+
result.first['indexesCreated'].map { |idx| idx['name'] }
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Drop the search index with the given id, or name. One or the other must
|
|
69
|
+
# be specified, but not both.
|
|
70
|
+
#
|
|
71
|
+
# @param [ String ] id the id of the index to drop
|
|
72
|
+
# @param [ String ] name the name of the index to drop
|
|
73
|
+
#
|
|
74
|
+
# @return [ Mongo::Operation::Result | false ] the result of the
|
|
75
|
+
# operation, or false if the given index does not exist.
|
|
76
|
+
def drop_one(id: nil, name: nil)
|
|
77
|
+
validate_id_or_name!(id, name)
|
|
78
|
+
|
|
79
|
+
spec = spec_with(index_id: id, index_name: name)
|
|
80
|
+
op = Operation::DropSearchIndex.new(spec)
|
|
81
|
+
|
|
82
|
+
# per the spec:
|
|
83
|
+
# Drivers MUST suppress NamespaceNotFound errors for the
|
|
84
|
+
# ``dropSearchIndex`` helper. Drop operations should be idempotent.
|
|
85
|
+
do_drop(op, nil, execution_context)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Iterate over the search indexes.
|
|
89
|
+
#
|
|
90
|
+
# @param [ Proc ] block if given, each search index will be yieleded to
|
|
91
|
+
# the block.
|
|
92
|
+
#
|
|
93
|
+
# @return [ self | Enumerator ] if a block is given, self is returned.
|
|
94
|
+
# Otherwise, an enumerator will be returned.
|
|
95
|
+
def each(&block)
|
|
96
|
+
@result ||= begin
|
|
97
|
+
spec = {}.tap do |s|
|
|
98
|
+
s[:id] = requested_index_id if requested_index_id
|
|
99
|
+
s[:name] = requested_index_name if requested_index_name
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
collection.aggregate(
|
|
103
|
+
[ { '$listSearchIndexes' => spec } ],
|
|
104
|
+
aggregate_options
|
|
105
|
+
)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
return @result.to_enum unless block
|
|
109
|
+
|
|
110
|
+
@result.each(&block)
|
|
111
|
+
self
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Update the search index with the given id or name. One or the other
|
|
115
|
+
# must be provided, but not both.
|
|
116
|
+
#
|
|
117
|
+
# @param [ Hash ] definition the definition to replace the given search
|
|
118
|
+
# index with.
|
|
119
|
+
# @param [ nil | String ] id the id of the search index to update
|
|
120
|
+
# @param [ nil | String ] name the name of the search index to update
|
|
121
|
+
#
|
|
122
|
+
# @return [ Mongo::Operation::Result ] the result of the operation
|
|
123
|
+
def update_one(definition, id: nil, name: nil)
|
|
124
|
+
validate_id_or_name!(id, name)
|
|
125
|
+
|
|
126
|
+
spec = spec_with(index_id: id, index_name: name, index: definition)
|
|
127
|
+
Operation::UpdateSearchIndex.new(spec).execute(next_primary, context: execution_context)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# The following methods are to make the view act more like an array,
|
|
131
|
+
# without having to explicitly make it an array...
|
|
132
|
+
|
|
133
|
+
# Queries whether the search index enumerable is empty.
|
|
134
|
+
#
|
|
135
|
+
# @return [ true | false ] whether the enumerable is empty or not.
|
|
136
|
+
def empty?
|
|
137
|
+
count.zero?
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
private
|
|
141
|
+
|
|
142
|
+
# A helper method for building the specification document with certain
|
|
143
|
+
# values pre-populated.
|
|
144
|
+
#
|
|
145
|
+
# @param [ Hash ] extras the values to put into the specification
|
|
146
|
+
#
|
|
147
|
+
# @return [ Hash ] the specification document
|
|
148
|
+
def spec_with(extras)
|
|
149
|
+
{
|
|
150
|
+
coll_name: collection.name,
|
|
151
|
+
db_name: collection.database.name,
|
|
152
|
+
}.merge(extras)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# A helper method for retrieving the primary server from the cluster.
|
|
156
|
+
#
|
|
157
|
+
# @return [ Mongo::Server ] the server to use
|
|
158
|
+
def next_primary(ping = nil, session = nil)
|
|
159
|
+
collection.cluster.next_primary(ping, session)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# A helper method for constructing a new operation context for executing
|
|
163
|
+
# an operation.
|
|
164
|
+
#
|
|
165
|
+
# @return [ Mongo::Operation::Context ] the operation context
|
|
166
|
+
def execution_context
|
|
167
|
+
Operation::Context.new(client: collection.client)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Validates the given id and name, ensuring that exactly one of them
|
|
171
|
+
# is non-nil.
|
|
172
|
+
#
|
|
173
|
+
# @param [ nil | String ] id the id to validate
|
|
174
|
+
# @param [ nil | String ] name the name to validate
|
|
175
|
+
#
|
|
176
|
+
# @raise [ ArgumentError ] if neither or both arguments are nil
|
|
177
|
+
def validate_id_or_name!(id, name)
|
|
178
|
+
return unless (id.nil? && name.nil?) || (!id.nil? && !name.nil?)
|
|
179
|
+
|
|
180
|
+
raise ArgumentError, 'exactly one of id or name must be specified'
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Validates the given search index document, ensuring that it has no
|
|
184
|
+
# extra keys, and that the name and definition are valid.
|
|
185
|
+
#
|
|
186
|
+
# @param [ Hash ] doc the document to validate
|
|
187
|
+
#
|
|
188
|
+
# @raise [ ArgumentError ] if the document is invalid.
|
|
189
|
+
def validate_search_index!(doc)
|
|
190
|
+
validate_search_index_keys!(doc.keys)
|
|
191
|
+
validate_search_index_name!(doc[:name] || doc['name'])
|
|
192
|
+
validate_search_index_definition!(doc[:definition] || doc['definition'])
|
|
193
|
+
doc
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Validates the keys of a search index document, ensuring that
|
|
197
|
+
# they are all valid.
|
|
198
|
+
#
|
|
199
|
+
# @param [ Array<String | Hash> ] keys the keys of a search index document
|
|
200
|
+
#
|
|
201
|
+
# @raise [ ArgumentError ] if the list contains any invalid keys
|
|
202
|
+
def validate_search_index_keys!(keys)
|
|
203
|
+
extras = keys - [ 'name', 'definition', :name, :definition ]
|
|
204
|
+
|
|
205
|
+
raise ArgumentError, "invalid keys in search index creation: #{extras.inspect}" if extras.any?
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Validates the name of a search index, ensuring that it is either a
|
|
209
|
+
# String or nil.
|
|
210
|
+
#
|
|
211
|
+
# @param [ nil | String ] name the name of a search index
|
|
212
|
+
#
|
|
213
|
+
# @raise [ ArgumentError ] if the name is not valid
|
|
214
|
+
def validate_search_index_name!(name)
|
|
215
|
+
return if name.nil? || name.is_a?(String)
|
|
216
|
+
|
|
217
|
+
raise ArgumentError, "search index name must be nil or a string (got #{name.inspect})"
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# Validates the definition of a search index.
|
|
221
|
+
#
|
|
222
|
+
# @param [ Hash ] definition the definition of a search index
|
|
223
|
+
#
|
|
224
|
+
# @raise [ ArgumentError ] if the definition is not valid
|
|
225
|
+
def validate_search_index_definition!(definition)
|
|
226
|
+
return if definition.is_a?(Hash)
|
|
227
|
+
|
|
228
|
+
raise ArgumentError, "search index definition must be a Hash (got #{definition.inspect})"
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|