mongo 2.15.0 → 2.17.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
- checksums.yaml.gz.sig +0 -0
- data/README.md +1 -1
- data/lib/mongo/auth/aws/request.rb +0 -1
- data/lib/mongo/bulk_write.rb +2 -2
- data/lib/mongo/client.rb +49 -5
- data/lib/mongo/cluster/periodic_executor.rb +4 -3
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +76 -43
- data/lib/mongo/cluster/sdam_flow.rb +9 -3
- data/lib/mongo/cluster/topology/base.rb +13 -9
- data/lib/mongo/cluster/topology/load_balanced.rb +102 -0
- data/lib/mongo/cluster/topology.rb +28 -8
- data/lib/mongo/cluster.rb +136 -51
- data/lib/mongo/collection/view/aggregation.rb +63 -23
- data/lib/mongo/collection/view/builder/aggregation.rb +16 -17
- data/lib/mongo/collection/view/builder/map_reduce.rb +12 -49
- data/lib/mongo/collection/view/builder.rb +0 -4
- data/lib/mongo/collection/view/change_stream.rb +7 -3
- data/lib/mongo/collection/view/iterable.rb +60 -27
- data/lib/mongo/collection/view/map_reduce.rb +41 -15
- data/lib/mongo/collection/view/readable.rb +84 -52
- data/lib/mongo/collection/view/writable.rb +201 -175
- data/lib/mongo/collection/view.rb +15 -21
- data/lib/mongo/collection.rb +34 -14
- data/lib/mongo/cursor/kill_spec.rb +38 -0
- data/lib/mongo/cursor.rb +72 -31
- data/lib/mongo/database/view.rb +5 -3
- data/lib/mongo/database.rb +6 -6
- data/lib/mongo/error/bad_load_balancer_target.rb +26 -0
- data/lib/mongo/error/missing_service_id.rb +26 -0
- data/lib/mongo/error/no_service_connection_available.rb +49 -0
- data/lib/mongo/error/notable.rb +7 -0
- data/lib/mongo/error/snapshot_session_invalid_server_version.rb +31 -0
- data/lib/mongo/error/snapshot_session_transaction_prohibited.rb +30 -0
- data/lib/mongo/error.rb +5 -0
- data/lib/mongo/grid/fs_bucket.rb +21 -2
- data/lib/mongo/id.rb +7 -5
- data/lib/mongo/index/view.rb +22 -41
- data/lib/mongo/monitoring/event/cmap/pool_cleared.rb +7 -4
- data/lib/mongo/monitoring/event/command_failed.rb +1 -1
- data/lib/mongo/monitoring/event/command_started.rb +2 -0
- data/lib/mongo/monitoring/publishable.rb +2 -2
- data/lib/mongo/operation/aggregate/command.rb +8 -0
- data/lib/mongo/operation/context.rb +19 -1
- data/lib/mongo/operation/count/command.rb +6 -0
- data/lib/mongo/operation/count/op_msg.rb +6 -0
- data/lib/mongo/operation/create/command.rb +7 -1
- data/lib/mongo/operation/create/op_msg.rb +7 -0
- data/lib/mongo/operation/create_index/command.rb +17 -1
- data/lib/mongo/operation/create_index/op_msg.rb +17 -4
- data/lib/mongo/operation/delete/command.rb +6 -3
- data/lib/mongo/operation/delete/legacy.rb +9 -2
- data/lib/mongo/operation/delete/op_msg.rb +9 -1
- data/lib/mongo/operation/distinct/command.rb +6 -0
- data/lib/mongo/operation/distinct/op_msg.rb +7 -0
- data/lib/mongo/operation/explain/command.rb +13 -1
- data/lib/mongo/operation/explain/legacy.rb +12 -5
- data/lib/mongo/operation/explain/op_msg.rb +9 -1
- data/lib/mongo/operation/find/builder/command.rb +111 -0
- data/lib/mongo/{collection/view → operation/find}/builder/flags.rb +10 -14
- data/lib/mongo/operation/find/builder/legacy.rb +123 -0
- data/lib/mongo/{collection/view → operation/find}/builder/modifiers.rb +31 -25
- data/lib/mongo/{cursor → operation/find}/builder.rb +4 -4
- data/lib/mongo/operation/find/command.rb +9 -0
- data/lib/mongo/operation/find/legacy.rb +10 -1
- data/lib/mongo/operation/find/op_msg.rb +12 -0
- data/lib/mongo/operation/find.rb +1 -0
- data/lib/mongo/operation/get_more/command.rb +1 -0
- data/lib/mongo/operation/get_more/command_builder.rb +38 -0
- data/lib/mongo/operation/get_more/op_msg.rb +1 -0
- data/lib/mongo/operation/get_more.rb +1 -0
- data/lib/mongo/operation/kill_cursors/command.rb +8 -0
- data/lib/mongo/operation/kill_cursors/command_builder.rb +35 -0
- data/lib/mongo/operation/kill_cursors/legacy.rb +2 -1
- data/lib/mongo/operation/kill_cursors/op_msg.rb +10 -0
- data/lib/mongo/operation/kill_cursors.rb +1 -0
- data/lib/mongo/operation/map_reduce/command.rb +8 -0
- data/lib/mongo/operation/map_reduce/op_msg.rb +1 -1
- data/lib/mongo/operation/result.rb +6 -0
- data/lib/mongo/operation/shared/executable.rb +19 -1
- data/lib/mongo/operation/shared/polymorphic_operation.rb +1 -1
- data/lib/mongo/operation/shared/read_preference_supported.rb +3 -1
- data/lib/mongo/operation/shared/response_handling.rb +1 -0
- data/lib/mongo/operation/shared/sessions_supported.rb +28 -12
- data/lib/mongo/operation/shared/specifiable.rb +11 -29
- data/lib/mongo/operation/shared/validatable.rb +87 -0
- data/lib/mongo/operation/shared/write.rb +1 -1
- data/lib/mongo/operation/update/command.rb +6 -3
- data/lib/mongo/operation/update/legacy.rb +19 -11
- data/lib/mongo/operation/update/op_msg.rb +8 -4
- data/lib/mongo/operation/write_command/command.rb +51 -0
- data/lib/mongo/operation/write_command/op_msg.rb +43 -0
- data/lib/mongo/operation/write_command.rb +32 -0
- data/lib/mongo/operation.rb +10 -0
- data/lib/mongo/protocol/query.rb +35 -18
- data/lib/mongo/server/connection.rb +25 -3
- data/lib/mongo/server/connection_base.rb +12 -1
- data/lib/mongo/server/connection_common.rb +38 -1
- data/lib/mongo/server/connection_pool/generation_manager.rb +71 -0
- data/lib/mongo/server/connection_pool.rb +100 -27
- data/lib/mongo/server/description/features.rb +20 -17
- data/lib/mongo/server/description/load_balancer.rb +33 -0
- data/lib/mongo/server/description.rb +85 -6
- data/lib/mongo/server/monitor/connection.rb +5 -6
- data/lib/mongo/server/monitor.rb +2 -1
- data/lib/mongo/server/pending_connection.rb +47 -31
- data/lib/mongo/server/push_monitor.rb +10 -1
- data/lib/mongo/server.rb +73 -26
- data/lib/mongo/server_selector/base.rb +31 -5
- data/lib/mongo/session/session_pool.rb +11 -0
- data/lib/mongo/session.rb +40 -1
- data/lib/mongo/socket/ocsp_cache.rb +2 -3
- data/lib/mongo/socket/ocsp_verifier.rb +6 -37
- data/lib/mongo/socket.rb +1 -5
- data/lib/mongo/uri/options_mapper.rb +1 -0
- data/lib/mongo/uri/srv_protocol.rb +6 -8
- data/lib/mongo/uri.rb +18 -0
- data/lib/mongo/utils.rb +0 -13
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +1 -1
- data/spec/integration/auth_spec.rb +31 -1
- data/spec/integration/awaited_ismaster_spec.rb +1 -1
- data/spec/integration/bulk_write_spec.rb +1 -1
- data/spec/integration/change_stream_spec.rb +3 -3
- data/spec/integration/client_construction_spec.rb +54 -0
- data/spec/integration/client_side_encryption/auto_encryption_bulk_writes_spec.rb +1 -1
- data/spec/integration/client_side_encryption/auto_encryption_command_monitoring_spec.rb +1 -1
- data/spec/integration/client_side_encryption/bson_size_limit_spec.rb +1 -1
- data/spec/integration/client_side_encryption/data_key_spec.rb +1 -1
- data/spec/integration/client_spec.rb +2 -0
- data/spec/integration/command_monitoring_spec.rb +1 -1
- data/spec/integration/command_spec.rb +1 -1
- data/spec/integration/connection_spec.rb +52 -35
- data/spec/integration/crud_spec.rb +174 -1
- data/spec/integration/cursor_pinning_spec.rb +121 -0
- data/spec/integration/cursor_reaping_spec.rb +8 -4
- data/spec/integration/fork_reconnect_spec.rb +1 -5
- data/spec/integration/get_more_spec.rb +1 -1
- data/spec/integration/heartbeat_events_spec.rb +1 -1
- data/spec/integration/map_reduce_spec.rb +77 -0
- data/spec/integration/query_cache_spec.rb +47 -2
- data/spec/integration/query_cache_transactions_spec.rb +1 -1
- data/spec/integration/read_concern_spec.rb +1 -1
- data/spec/integration/read_preference_spec.rb +17 -13
- data/spec/integration/reconnect_spec.rb +30 -12
- data/spec/integration/retryable_errors_spec.rb +1 -1
- data/spec/integration/retryable_writes/retryable_writes_36_and_older_spec.rb +1 -1
- data/spec/integration/retryable_writes/retryable_writes_40_and_newer_spec.rb +1 -1
- data/spec/integration/sdam_error_handling_spec.rb +5 -3
- data/spec/integration/sdam_events_spec.rb +35 -19
- data/spec/integration/sdam_prose_spec.rb +1 -1
- data/spec/integration/server_monitor_spec.rb +1 -0
- data/spec/integration/server_selector_spec.rb +22 -5
- data/spec/integration/server_spec.rb +2 -0
- data/spec/integration/srv_monitoring_spec.rb +1 -1
- data/spec/integration/step_down_spec.rb +1 -1
- data/spec/integration/transaction_pinning_spec.rb +120 -0
- data/spec/integration/versioned_api_examples_spec.rb +45 -0
- data/spec/integration/x509_auth_spec.rb +1 -1
- data/spec/lite_spec_helper.rb +1 -2
- data/spec/mongo/address/unix_spec.rb +1 -0
- data/spec/mongo/auth/cr_spec.rb +2 -3
- data/spec/mongo/auth/ldap_spec.rb +2 -3
- data/spec/mongo/auth/scram_spec.rb +2 -3
- data/spec/mongo/auth/user/view_spec.rb +1 -1
- data/spec/mongo/auth/x509_spec.rb +2 -3
- data/spec/mongo/bulk_write_spec.rb +3 -3
- data/spec/mongo/client_construction_spec.rb +259 -28
- data/spec/mongo/client_spec.rb +6 -4
- data/spec/mongo/cluster/cursor_reaper_spec.rb +36 -21
- data/spec/mongo/cluster/periodic_executor_spec.rb +3 -1
- data/spec/mongo/cluster_spec.rb +44 -3
- data/spec/mongo/collection/view/aggregation_spec.rb +72 -96
- data/spec/mongo/collection/view/builder/find_command_spec.rb +4 -0
- data/spec/mongo/collection/view/builder/op_query_spec.rb +4 -0
- data/spec/mongo/collection/view/change_stream_spec.rb +1 -1
- data/spec/mongo/collection/view/map_reduce_spec.rb +15 -2
- data/spec/mongo/collection_crud_spec.rb +7 -2
- data/spec/mongo/collection_ddl_spec.rb +1 -1
- data/spec/mongo/collection_spec.rb +1 -1
- data/spec/mongo/cursor/builder/get_more_command_spec.rb +4 -0
- data/spec/mongo/cursor/builder/op_get_more_spec.rb +4 -0
- data/spec/mongo/cursor_spec.rb +15 -5
- data/spec/mongo/database_spec.rb +15 -15
- data/spec/mongo/error/operation_failure_heavy_spec.rb +1 -1
- data/spec/mongo/grid/fs_bucket_spec.rb +18 -12
- data/spec/mongo/grid/stream/write_spec.rb +3 -9
- data/spec/mongo/grid/stream_spec.rb +1 -1
- data/spec/mongo/index/view_spec.rb +2 -2
- data/spec/mongo/operation/delete/op_msg_spec.rb +1 -1
- data/spec/mongo/{collection/view → operation/find}/builder/flags_spec.rb +2 -2
- data/spec/mongo/{collection/view → operation/find}/builder/modifiers_spec.rb +2 -2
- data/spec/mongo/operation/find/legacy_spec.rb +1 -0
- data/spec/mongo/operation/insert/bulk_spec.rb +1 -1
- data/spec/mongo/operation/insert/op_msg_spec.rb +1 -1
- data/spec/mongo/operation/kill_cursors_spec.rb +4 -1
- data/spec/mongo/operation/read_preference_legacy_spec.rb +4 -0
- data/spec/mongo/operation/read_preference_op_msg_spec.rb +26 -1
- data/spec/mongo/operation/update/bulk_spec.rb +1 -1
- data/spec/mongo/operation/update/op_msg_spec.rb +1 -1
- data/spec/mongo/query_cache_spec.rb +6 -2
- data/spec/mongo/server/connection_common_spec.rb +62 -11
- data/spec/mongo/server/connection_pool_spec.rb +73 -7
- data/spec/mongo/server/connection_spec.rb +138 -43
- data/spec/mongo/server/description_spec.rb +1 -1
- data/spec/mongo/server/monitor/connection_spec.rb +22 -0
- data/spec/mongo/server/monitor_spec.rb +4 -3
- data/spec/mongo/server/push_monitor_spec.rb +101 -0
- data/spec/mongo/server_selector_spec.rb +136 -15
- data/spec/mongo/session/session_pool_spec.rb +42 -10
- data/spec/mongo/session_transaction_spec.rb +15 -30
- data/spec/mongo/socket/ssl_spec.rb +26 -58
- data/spec/mongo/socket/unix_spec.rb +1 -0
- data/spec/mongo/uri_option_parsing_spec.rb +38 -5
- data/spec/mongo/utils_spec.rb +0 -14
- data/spec/runners/change_streams/test.rb +1 -1
- data/spec/runners/cmap.rb +1 -1
- data/spec/runners/connection_string.rb +7 -3
- data/spec/runners/crud/operation.rb +5 -3
- data/spec/runners/crud/requirement.rb +1 -0
- data/spec/runners/crud/verifier.rb +1 -2
- data/spec/runners/crud.rb +1 -1
- data/spec/runners/sdam.rb +2 -1
- data/spec/runners/transactions/test.rb +2 -2
- data/spec/runners/unified/assertions.rb +5 -4
- data/spec/runners/unified/crud_operations.rb +77 -23
- data/spec/runners/unified/ddl_operations.rb +29 -1
- data/spec/runners/unified/entity_map.rb +3 -3
- data/spec/runners/unified/event_subscriber.rb +2 -2
- data/spec/runners/unified/support_operations.rb +16 -3
- data/spec/runners/unified/test.rb +18 -3
- data/spec/runners/unified.rb +1 -1
- data/spec/shared/lib/mrss/cluster_config.rb +6 -1
- data/spec/shared/lib/mrss/constraints.rb +11 -5
- data/spec/shared/lib/mrss/event_subscriber.rb +200 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +17 -12
- data/spec/shared/share/Dockerfile.erb +5 -4
- data/spec/shared/shlib/server.sh +70 -20
- data/spec/spec_tests/change_streams_spec.rb +1 -1
- data/spec/spec_tests/cmap_spec.rb +4 -1
- data/spec/spec_tests/command_monitoring_spec.rb +2 -2
- data/spec/spec_tests/data/command_monitoring/find.yml +9 -9
- data/spec/spec_tests/data/crud/read/aggregate-collation.yml +2 -1
- data/spec/spec_tests/data/crud/read/aggregate-out.yml +1 -0
- data/spec/spec_tests/data/crud/read/count-collation.yml +2 -1
- data/spec/spec_tests/data/crud/read/distinct-collation.yml +2 -1
- data/spec/spec_tests/data/crud/read/find-collation.yml +2 -1
- data/spec/spec_tests/data/crud/write/bulkWrite-collation.yml +2 -1
- data/spec/spec_tests/data/crud/write/deleteMany-collation.yml +2 -1
- data/spec/spec_tests/data/crud/write/deleteOne-collation.yml +2 -1
- data/spec/spec_tests/data/crud/write/findOneAndDelete-collation.yml +3 -2
- data/spec/spec_tests/data/crud/write/findOneAndReplace-collation.yml +2 -1
- data/spec/spec_tests/data/crud/write/findOneAndUpdate-collation.yml +3 -2
- data/spec/spec_tests/data/crud/write/replaceOne-collation.yml +3 -2
- data/spec/spec_tests/data/crud/write/updateMany-collation.yml +2 -1
- data/spec/spec_tests/data/crud/write/updateOne-collation.yml +2 -1
- data/spec/spec_tests/data/crud_unified/aggregate-let.yml +138 -0
- data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +155 -0
- data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +151 -0
- data/spec/spec_tests/data/crud_unified/deleteMany-let.yml +91 -0
- data/spec/spec_tests/data/crud_unified/deleteOne-let.yml +89 -0
- data/spec/spec_tests/data/crud_unified/find-let.yml +71 -0
- data/spec/spec_tests/data/crud_unified/findOneAndDelete-let.yml +88 -0
- data/spec/spec_tests/data/crud_unified/findOneAndReplace-let.yml +94 -0
- data/spec/spec_tests/data/crud_unified/findOneAndUpdate-let.yml +96 -0
- data/spec/spec_tests/data/crud_unified/updateMany-let.yml +103 -0
- data/spec/spec_tests/data/crud_unified/updateOne-let.yml +98 -0
- data/spec/spec_tests/data/load_balancers/event-monitoring.yml +99 -0
- data/spec/spec_tests/data/load_balancers/lb-connection-establishment.yml +36 -0
- data/spec/spec_tests/data/load_balancers/non-lb-connection-establishment.yml +56 -0
- data/spec/spec_tests/data/load_balancers/server-selection.yml +50 -0
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Nearest.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Nearest2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/Secondary.yml +4 -4
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.yml +4 -4
- data/spec/spec_tests/data/max_staleness/ReplicaSetNoPrimary/ZeroMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LongHeartbeat.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/LongHeartbeat2.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Nearest_tags.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.yml +2 -2
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.yml +5 -5
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Secondary_tags.yml +5 -5
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.yml +3 -3
- data/spec/spec_tests/data/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/Sharded/SmallMaxStaleness.yml +2 -2
- data/spec/spec_tests/data/max_staleness/Single/SmallMaxStaleness.yml +1 -1
- data/spec/spec_tests/data/max_staleness/Unknown/SmallMaxStaleness.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/changeStreams-client.watch.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.coll.watch.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch-serverErrors.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/changeStreams-db.watch.yml +1 -1
- data/spec/spec_tests/data/retryable_reads/mapReduce.yml +3 -1
- data/spec/spec_tests/data/sdam/load-balanced/discover_load_balancer.yml +25 -0
- data/spec/spec_tests/data/sdam_integration/find-network-error.yml +2 -0
- data/spec/spec_tests/data/sdam_integration/find-shutdown-error.yml +2 -0
- data/spec/spec_tests/data/sdam_integration/hello-command-error.yml +3 -1
- data/spec/spec_tests/data/sdam_integration/hello-network-error.yml +3 -1
- data/spec/spec_tests/data/sdam_integration/hello-timeout.yml +2 -0
- data/spec/spec_tests/data/sdam_integration/insert-network-error.yml +2 -0
- data/spec/spec_tests/data/sdam_integration/insert-shutdown-error.yml +2 -0
- data/spec/spec_tests/data/sdam_monitoring/load_balancer.yml +65 -0
- data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-directConnection.yml +13 -0
- data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-replicaSet-errors.yml +6 -0
- data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-true-multiple-hosts.yml +5 -0
- data/spec/spec_tests/data/seed_list_discovery/load-balanced/loadBalanced-true-txt.yml +10 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/direct-connection-false.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/direct-connection-true.yml +0 -0
- data/spec/spec_tests/data/seed_list_discovery/replica-set/encoded-userinfo-and-db.yml +15 -0
- data/spec/spec_tests/data/seed_list_discovery/replica-set/loadBalanced-false-txt.yml +10 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/longer-parent-in-return.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/misformatted-option.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/no-results.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/not-enough-parts.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-result-default-port.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-txt-record-multiple-strings.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/one-txt-record.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch1.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch2.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch3.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch4.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/parent-part-mismatch5.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/returned-parent-too-short.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/returned-parent-wrong.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-results-default-port.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-results-nonstandard-port.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/two-txt-records.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-not-allowed-option.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-overridden-ssl-option.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-overridden-uri-option.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/txt-record-with-unallowed-option.yml +0 -0
- data/spec/spec_tests/data/seed_list_discovery/replica-set/uri-with-admin-database.yml +13 -0
- data/spec/spec_tests/data/seed_list_discovery/replica-set/uri-with-auth.yml +12 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/uri-with-port.yml +0 -0
- data/spec/spec_tests/data/{dns_seedlist_discovery → seed_list_discovery/replica-set}/uri-with-two-hosts.yml +0 -0
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions-not-supported-client-error.yml +69 -0
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions-not-supported-server-error.yml +102 -0
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions-unsupported-ops.yml +258 -0
- data/spec/spec_tests/data/sessions_unified/snapshot-sessions.yml +482 -0
- data/spec/spec_tests/data/transactions/retryable-abort-errorLabels.yml +2 -0
- data/spec/spec_tests/data/transactions/retryable-abort.yml +2 -0
- data/spec/spec_tests/data/transactions/retryable-commit-errorLabels.yml +2 -0
- data/spec/spec_tests/data/transactions/retryable-commit.yml +2 -0
- data/spec/spec_tests/data/transactions/retryable-writes.yml +2 -0
- data/spec/spec_tests/data/uri_options/connection-options.yml +60 -0
- data/spec/spec_tests/load_balancers_spec.rb +15 -0
- data/spec/spec_tests/retryable_reads_spec.rb +2 -2
- data/spec/spec_tests/retryable_writes_spec.rb +1 -1
- data/spec/spec_tests/sdam_integration_spec.rb +1 -1
- data/spec/spec_tests/sdam_monitoring_spec.rb +10 -5
- data/spec/spec_tests/sdam_spec.rb +1 -1
- data/spec/spec_tests/seed_list_discovery_spec.rb +118 -0
- data/spec/spec_tests/sessions_unified_spec.rb +13 -0
- data/spec/spec_tests/uri_options_spec.rb +4 -4
- data/spec/stress/fork_reconnect_stress_spec.rb +1 -5
- data/spec/stress/push_monitor_close_spec.rb +44 -0
- data/spec/support/certificates/atlas-ocsp-ca.crt +82 -90
- data/spec/support/certificates/atlas-ocsp.crt +127 -122
- data/spec/support/common_shortcuts.rb +2 -3
- data/spec/support/matchers.rb +13 -0
- data/spec/support/shared/auth_context.rb +16 -0
- data/spec/support/shared/session.rb +2 -2
- data/spec/support/spec_config.rb +10 -11
- data/spec/support/using_hash.rb +31 -0
- data/spec/support/utils.rb +1 -1
- data.tar.gz.sig +3 -4
- metadata +1111 -1029
- metadata.gz.sig +2 -3
- data/lib/mongo/collection/view/builder/find_command.rb +0 -173
- data/lib/mongo/collection/view/builder/op_query.rb +0 -94
- data/lib/mongo/cursor/builder/get_more_command.rb +0 -80
- data/lib/mongo/cursor/builder/kill_cursors_command.rb +0 -111
- data/lib/mongo/cursor/builder/op_get_more.rb +0 -64
- data/lib/mongo/cursor/builder/op_kill_cursors.rb +0 -106
- data/lib/mongo/server/context.rb +0 -72
- data/spec/mongo/cursor/builder/op_kill_cursors_spec.rb +0 -66
- data/spec/runners/unified/using_hash.rb +0 -34
- data/spec/spec_tests/dns_seedlist_discovery_spec.rb +0 -79
- data/spec/support/event_subscriber.rb +0 -221
@@ -194,13 +194,12 @@ module Mongo
|
|
194
194
|
#
|
195
195
|
# @raise [Mongo::Error] If handshake failed.
|
196
196
|
def handshake!
|
197
|
-
|
198
|
-
|
199
|
-
|
197
|
+
command = handshake_command(
|
198
|
+
handshake_document(
|
199
|
+
@app_metadata,
|
200
|
+
server_api: options[:server_api]
|
201
|
+
)
|
200
202
|
)
|
201
|
-
# TODO (DR): OP_MSG should be used if api version is declared.
|
202
|
-
# See https://github.com/mongodb/specifications/blob/master/source/message/OP_MSG.rst#id5
|
203
|
-
command = Protocol::Query.new(Database::ADMIN, Database::COMMAND, document, :limit => -1)
|
204
203
|
payload = command.serialize.to_s
|
205
204
|
message = dispatch_bytes(payload)
|
206
205
|
result = Operation::Result.new(message)
|
data/lib/mongo/server/monitor.rb
CHANGED
@@ -215,7 +215,8 @@ module Mongo
|
|
215
215
|
old_description = server.description
|
216
216
|
|
217
217
|
new_description = Description.new(server.address, result,
|
218
|
-
server.round_trip_time_averager.average_round_trip_time
|
218
|
+
average_round_trip_time: server.round_trip_time_averager.average_round_trip_time
|
219
|
+
)
|
219
220
|
|
220
221
|
server.cluster.run_sdam_flow(server.description, new_description, awaited: awaited)
|
221
222
|
|
@@ -71,32 +71,41 @@ module Mongo
|
|
71
71
|
raise Error::InternalDriverError, "Connection description cannot be unknown after successful handshake: #{description.inspect}"
|
72
72
|
end
|
73
73
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
74
|
+
begin
|
75
|
+
if speculative_auth_doc && (speculative_auth_result = result['speculativeAuthenticate'])
|
76
|
+
unless description.features.scram_sha_1_enabled?
|
77
|
+
raise Error::InvalidServerAuthResponse, "Speculative auth succeeded on a pre-3.0 server"
|
78
|
+
end
|
79
|
+
case speculative_auth_user.mechanism
|
80
|
+
when :mongodb_x509
|
81
|
+
# Done
|
82
|
+
# We default auth mechanism to scram256, but if user specified
|
83
|
+
# scram explicitly we may be able to authenticate speculatively
|
84
|
+
# with scram.
|
85
|
+
when :scram, :scram256
|
86
|
+
authenticate!(
|
87
|
+
speculative_auth_client_nonce: speculative_auth.conversation.client_nonce,
|
88
|
+
speculative_auth_mech: speculative_auth_user.mechanism,
|
89
|
+
speculative_auth_result: speculative_auth_result,
|
90
|
+
)
|
91
|
+
else
|
92
|
+
raise Error::InternalDriverError, "Speculative auth unexpectedly succeeded for mechanism #{speculative_auth_user.mechanism.inspect}"
|
93
|
+
end
|
94
|
+
elsif !description.arbiter?
|
95
|
+
authenticate!
|
92
96
|
end
|
93
|
-
|
94
|
-
|
97
|
+
rescue Mongo::Error, Mongo::Error::AuthError => exc
|
98
|
+
exc.service_id = service_id
|
99
|
+
raise
|
95
100
|
end
|
96
101
|
|
97
102
|
if description.unknown?
|
98
103
|
raise Error::InternalDriverError, "Connection description cannot be unknown after successful authentication: #{description.inspect}"
|
99
104
|
end
|
105
|
+
|
106
|
+
if server.load_balancer? && !description.mongos?
|
107
|
+
raise Error::BadLoadBalancerTarget, "Load-balanced operation requires being connected a mongos, but the server at #{address.seed} reported itself as #{description.server_type.to_s.gsub('_', ' ')}"
|
108
|
+
end
|
100
109
|
end
|
101
110
|
|
102
111
|
private
|
@@ -111,16 +120,14 @@ module Mongo
|
|
111
120
|
raise Error::InternalDriverError, "Cannot handshake because there is no usable socket (for #{address})"
|
112
121
|
end
|
113
122
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
123
|
+
hello_command = handshake_command(
|
124
|
+
handshake_document(
|
125
|
+
app_metadata,
|
126
|
+
speculative_auth_doc: speculative_auth_doc,
|
127
|
+
load_balancer: server.load_balancer?,
|
128
|
+
server_api: options[:server_api]
|
129
|
+
)
|
118
130
|
)
|
119
|
-
|
120
|
-
# TODO (DR): OP_MSG should be used if api version is declared.
|
121
|
-
# See https://github.com/mongodb/specifications/blob/master/source/message/OP_MSG.rst#id5
|
122
|
-
hello_command = Protocol::Query.new(Database::ADMIN, Database::COMMAND, hello_doc, :limit => -1)
|
123
|
-
|
124
131
|
doc = nil
|
125
132
|
@server.handle_handshake_failure! do
|
126
133
|
begin
|
@@ -144,6 +151,10 @@ module Mongo
|
|
144
151
|
end
|
145
152
|
end
|
146
153
|
|
154
|
+
if @server.force_load_balancer?
|
155
|
+
doc['serviceId'] ||= "fake:#{rand(2**32-1)+1}"
|
156
|
+
end
|
157
|
+
|
147
158
|
post_handshake(doc, @server.round_trip_time_averager.average_round_trip_time)
|
148
159
|
|
149
160
|
doc
|
@@ -193,7 +204,7 @@ module Mongo
|
|
193
204
|
# This is a separate method to keep the nesting level down.
|
194
205
|
#
|
195
206
|
# @return [ Server::Description ] The server description calculated from
|
196
|
-
#
|
207
|
+
# the handshake response for this particular connection.
|
197
208
|
def post_handshake(response, average_rtt)
|
198
209
|
if response["ok"] == 1
|
199
210
|
# Auth mechanism is entirely dependent on the contents of
|
@@ -210,7 +221,12 @@ module Mongo
|
|
210
221
|
@sasl_supported_mechanisms = nil
|
211
222
|
end
|
212
223
|
|
213
|
-
@description = Description.new(
|
224
|
+
@description = Description.new(
|
225
|
+
address, response,
|
226
|
+
average_round_trip_time: average_rtt,
|
227
|
+
load_balancer: server.load_balancer?,
|
228
|
+
force_load_balancer: options[:connect] == :load_balanced,
|
229
|
+
).tap do |new_description|
|
214
230
|
@server.cluster.run_sdam_flow(@server.description, new_description)
|
215
231
|
end
|
216
232
|
end
|
@@ -110,13 +110,22 @@ module Mongo
|
|
110
110
|
if new_description.topology_version
|
111
111
|
@topology_version = new_description.topology_version
|
112
112
|
end
|
113
|
-
rescue Mongo::Error => exc
|
113
|
+
rescue IOError, SocketError, SystemCallError, Mongo::Error => exc
|
114
|
+
stop_requested = @lock.synchronize { @stop_requested }
|
115
|
+
if stop_requested
|
116
|
+
# Ignore the exception, see RUBY-2771.
|
117
|
+
return
|
118
|
+
end
|
119
|
+
|
114
120
|
msg = "Error running awaited hello on #{server.address}"
|
115
121
|
Utils.warn_bg_exception(msg, exc,
|
116
122
|
logger: options[:logger],
|
117
123
|
log_prefix: options[:log_prefix],
|
118
124
|
bg_error_backtrace: options[:bg_error_backtrace],
|
119
125
|
)
|
126
|
+
|
127
|
+
# Avoid tight looping in push monitor - see RUBY-2806.
|
128
|
+
sleep(0.5)
|
120
129
|
end
|
121
130
|
|
122
131
|
def check
|
data/lib/mongo/server.rb
CHANGED
@@ -54,6 +54,9 @@ module Mongo
|
|
54
54
|
# done by this server. Note: setting this option to false will make
|
55
55
|
# the server non-functional. It is intended for use in tests which
|
56
56
|
# manually invoke SDAM state transitions.
|
57
|
+
# @option options [ true | false ] :load_balancer Whether this server
|
58
|
+
# is a load balancer.
|
59
|
+
# @option options [ String ] :connect The client connection mode.
|
57
60
|
#
|
58
61
|
# @since 2.0.0
|
59
62
|
def initialize(address, cluster, monitoring, event_listeners, options = {})
|
@@ -69,7 +72,10 @@ module Mongo
|
|
69
72
|
end
|
70
73
|
@scan_semaphore = DistinguishingSemaphore.new
|
71
74
|
@round_trip_time_averager = RoundTripTimeAverager.new
|
72
|
-
@description = Description.new(address, {}
|
75
|
+
@description = Description.new(address, {},
|
76
|
+
load_balancer: !!@options[:load_balancer],
|
77
|
+
force_load_balancer: force_load_balancer?,
|
78
|
+
)
|
73
79
|
@last_scan = nil
|
74
80
|
@last_scan_monotime = nil
|
75
81
|
unless options[:monitoring_io] == false
|
@@ -107,6 +113,15 @@ module Mongo
|
|
107
113
|
# description the monitor refreshes.
|
108
114
|
attr_reader :description
|
109
115
|
|
116
|
+
# Returns whether this server is forced to be a load balancer.
|
117
|
+
#
|
118
|
+
# @return [ true | false ] Whether this server is forced to be a load balancer.
|
119
|
+
#
|
120
|
+
# @api private
|
121
|
+
def force_load_balancer?
|
122
|
+
options[:connect] == :load_balanced
|
123
|
+
end
|
124
|
+
|
110
125
|
# @return [ Time | nil ] last_scan The time when the last server scan
|
111
126
|
# completed, or nil if the server has not been scanned yet.
|
112
127
|
#
|
@@ -180,6 +195,7 @@ module Mongo
|
|
180
195
|
:secondary?,
|
181
196
|
:standalone?,
|
182
197
|
:unknown?,
|
198
|
+
:load_balancer?,
|
183
199
|
:last_write_date,
|
184
200
|
:logical_session_timeout
|
185
201
|
|
@@ -222,20 +238,6 @@ module Mongo
|
|
222
238
|
address == other.address
|
223
239
|
end
|
224
240
|
|
225
|
-
# Get a new context for this server in which to send messages.
|
226
|
-
#
|
227
|
-
# @example Get the server context.
|
228
|
-
# server.context
|
229
|
-
#
|
230
|
-
# @return [ Mongo::Server::Context ] context The server context.
|
231
|
-
#
|
232
|
-
# @since 2.0.0
|
233
|
-
#
|
234
|
-
# @deprecated Will be removed in version 3.0
|
235
|
-
def context
|
236
|
-
Context.new(self)
|
237
|
-
end
|
238
|
-
|
239
241
|
# Determine if a connection to the server is able to be established and
|
240
242
|
# messages can be sent to it.
|
241
243
|
#
|
@@ -301,13 +303,20 @@ module Mongo
|
|
301
303
|
#
|
302
304
|
# @api private
|
303
305
|
def start_monitoring
|
306
|
+
publish_opening_event
|
307
|
+
if options[:monitoring_io] != false
|
308
|
+
monitor.run!
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
# Publishes the server opening event.
|
313
|
+
#
|
314
|
+
# @api private
|
315
|
+
def publish_opening_event
|
304
316
|
publish_sdam_event(
|
305
317
|
Monitoring::SERVER_OPENING,
|
306
318
|
Monitoring::Event::ServerOpening.new(address, cluster.topology)
|
307
319
|
)
|
308
|
-
if options[:monitoring_io] != false
|
309
|
-
monitor.run!
|
310
|
-
end
|
311
320
|
end
|
312
321
|
|
313
322
|
# Get a pretty printed server inspection.
|
@@ -327,6 +336,8 @@ module Mongo
|
|
327
336
|
# @api private
|
328
337
|
def status
|
329
338
|
case
|
339
|
+
when load_balancer?
|
340
|
+
'LB'
|
330
341
|
when primary?
|
331
342
|
'PRIMARY'
|
332
343
|
when secondary?
|
@@ -433,8 +444,8 @@ module Mongo
|
|
433
444
|
# @return [ Object ] The result of the block execution.
|
434
445
|
#
|
435
446
|
# @since 2.3.0
|
436
|
-
def with_connection(&block)
|
437
|
-
pool.with_connection(&block)
|
447
|
+
def with_connection(service_id: nil, &block)
|
448
|
+
pool.with_connection(service_id: service_id, &block)
|
438
449
|
end
|
439
450
|
|
440
451
|
# Handle handshake failure.
|
@@ -444,7 +455,11 @@ module Mongo
|
|
444
455
|
def handle_handshake_failure!
|
445
456
|
yield
|
446
457
|
rescue Mongo::Error::SocketError, Mongo::Error::SocketTimeoutError => e
|
447
|
-
unknown!(
|
458
|
+
unknown!(
|
459
|
+
generation: e.generation,
|
460
|
+
service_id: e.service_id,
|
461
|
+
stop_push_monitor: true,
|
462
|
+
)
|
448
463
|
raise
|
449
464
|
end
|
450
465
|
|
@@ -467,7 +482,11 @@ module Mongo
|
|
467
482
|
raise
|
468
483
|
rescue Mongo::Error::SocketError => e
|
469
484
|
# non-timeout network error
|
470
|
-
unknown!(
|
485
|
+
unknown!(
|
486
|
+
generation: e.generation,
|
487
|
+
service_id: e.service_id,
|
488
|
+
stop_push_monitor: true,
|
489
|
+
)
|
471
490
|
raise
|
472
491
|
rescue Auth::Unauthorized
|
473
492
|
# auth error, keep server description and topology as they are
|
@@ -513,13 +532,33 @@ module Mongo
|
|
513
532
|
# respective server is cleared. Set this option to true to keep the
|
514
533
|
# existing connection pool (required when handling not master errors
|
515
534
|
# on 4.2+ servers).
|
535
|
+
# @option options [ Object ] :service_id Discard state for the specified
|
536
|
+
# service id only.
|
516
537
|
# @option options [ TopologyVersion ] :topology_version Topology version
|
517
538
|
# of the error response that is causing the server to be marked unknown.
|
518
539
|
# @option options [ true | false ] :stop_push_monitor Whether to stop
|
519
540
|
# the PushMonitor associated with the server, if any.
|
541
|
+
# @option options [ Object ] :service_id Discard state for the specified
|
542
|
+
# service id only.
|
520
543
|
#
|
521
544
|
# @since 2.4.0, SDAM events are sent as of version 2.7.0
|
522
545
|
def unknown!(options = {})
|
546
|
+
if load_balancer?
|
547
|
+
# When the client is in load-balanced topology, servers (the one and
|
548
|
+
# only that can be) starts out as a load balancer and stays as a
|
549
|
+
# load balancer indefinitely. As such it is not marked unknown.
|
550
|
+
#
|
551
|
+
# However, this method also clears connection pool for the server
|
552
|
+
# when the latter is marked unknown, and this part needs to happen
|
553
|
+
# when the server is a load balancer.
|
554
|
+
if service_id = options[:service_id]
|
555
|
+
pool.disconnect!(service_id: service_id)
|
556
|
+
elsif Lint.enabled?
|
557
|
+
raise Error::LintError, 'Load balancer was asked to be marked unknown without a service id'
|
558
|
+
end
|
559
|
+
return
|
560
|
+
end
|
561
|
+
|
523
562
|
if options[:generation] && options[:generation] < pool.generation
|
524
563
|
return
|
525
564
|
end
|
@@ -537,10 +576,16 @@ module Mongo
|
|
537
576
|
# SDAM flow will update description on the server without in-place
|
538
577
|
# mutations and invoke SDAM transitions as needed.
|
539
578
|
config = {}
|
579
|
+
if options[:service_id]
|
580
|
+
config['serviceId'] = options[:service_id]
|
581
|
+
end
|
540
582
|
if options[:topology_version]
|
541
583
|
config['topologyVersion'] = options[:topology_version]
|
542
584
|
end
|
543
|
-
new_description = Description.new(address, config
|
585
|
+
new_description = Description.new(address, config,
|
586
|
+
load_balancer: load_balancer?,
|
587
|
+
force_load_balancer: options[:connect] == :load_balanced,
|
588
|
+
)
|
544
589
|
cluster.run_sdam_flow(description, new_description, options)
|
545
590
|
end
|
546
591
|
|
@@ -549,11 +594,14 @@ module Mongo
|
|
549
594
|
@description = description
|
550
595
|
end
|
551
596
|
|
597
|
+
# @param [ Object ] :service_id Close connections with the specified
|
598
|
+
# service id only.
|
599
|
+
#
|
552
600
|
# @api private
|
553
|
-
def clear_connection_pool
|
601
|
+
def clear_connection_pool(service_id: nil)
|
554
602
|
@pool_lock.synchronize do
|
555
603
|
if @pool
|
556
|
-
@pool.disconnect!
|
604
|
+
@pool.disconnect!(service_id: service_id)
|
557
605
|
end
|
558
606
|
end
|
559
607
|
end
|
@@ -577,7 +625,6 @@ require 'mongo/server/connection_base'
|
|
577
625
|
require 'mongo/server/pending_connection'
|
578
626
|
require 'mongo/server/connection'
|
579
627
|
require 'mongo/server/connection_pool'
|
580
|
-
require 'mongo/server/context'
|
581
628
|
require 'mongo/server/description'
|
582
629
|
require 'mongo/server/monitor'
|
583
630
|
require 'mongo/server/round_trip_time_averager'
|
@@ -162,6 +162,8 @@ module Mongo
|
|
162
162
|
# Deprecated and ignored.
|
163
163
|
# @param [ Session | nil ] session Optional session to take into account
|
164
164
|
# for mongos pinning. Added in version 2.10.0.
|
165
|
+
# @param [ true | false ] write_aggregation Whether we need a server that
|
166
|
+
# supports writing aggregations (e.g. with $merge/$out) on secondaries.
|
165
167
|
#
|
166
168
|
# @return [ Mongo::Server ] A server matching the server preference.
|
167
169
|
#
|
@@ -172,7 +174,11 @@ module Mongo
|
|
172
174
|
# lint mode is enabled.
|
173
175
|
#
|
174
176
|
# @since 2.0.0
|
175
|
-
def select_server(cluster, ping = nil, session = nil)
|
177
|
+
def select_server(cluster, ping = nil, session = nil, write_aggregation: false)
|
178
|
+
if cluster.topology.is_a?(Cluster::Topology::LoadBalanced)
|
179
|
+
return cluster.servers.first
|
180
|
+
end
|
181
|
+
|
176
182
|
server_selection_timeout = cluster.options[:server_selection_timeout] || SERVER_SELECTION_TIMEOUT
|
177
183
|
|
178
184
|
# Special handling for zero timeout: if we have to select a server,
|
@@ -239,7 +245,7 @@ module Mongo
|
|
239
245
|
=end
|
240
246
|
|
241
247
|
loop do
|
242
|
-
server = try_select_server(cluster)
|
248
|
+
server = try_select_server(cluster, write_aggregation: write_aggregation)
|
243
249
|
|
244
250
|
if server
|
245
251
|
unless cluster.topology.compatible?
|
@@ -247,7 +253,7 @@ module Mongo
|
|
247
253
|
end
|
248
254
|
|
249
255
|
if session && session.starting_transaction? && cluster.sharded?
|
250
|
-
session.
|
256
|
+
session.pin_to_server(server)
|
251
257
|
end
|
252
258
|
|
253
259
|
return server
|
@@ -290,11 +296,31 @@ module Mongo
|
|
290
296
|
# Tries to find a suitable server, returns the server if one is available
|
291
297
|
# or nil if there isn't a suitable server.
|
292
298
|
#
|
299
|
+
# @param [ Mongo::Cluster ] cluster The cluster from which to select
|
300
|
+
# an eligible server.
|
301
|
+
# @param [ true | false ] write_aggregation Whether we need a server that
|
302
|
+
# supports writing aggregations (e.g. with $merge/$out) on secondaries.
|
303
|
+
#
|
293
304
|
# @return [ Server | nil ] A suitable server, if one exists.
|
294
305
|
#
|
295
306
|
# @api private
|
296
|
-
def try_select_server(cluster)
|
297
|
-
servers =
|
307
|
+
def try_select_server(cluster, write_aggregation: false)
|
308
|
+
servers = if write_aggregation && cluster.replica_set?
|
309
|
+
# 1. Check if ALL servers in cluster support secondary writes.
|
310
|
+
is_write_supported = cluster.servers.reduce(true) do |res, server|
|
311
|
+
res && server.features.merge_out_on_secondary_enabled?
|
312
|
+
end
|
313
|
+
|
314
|
+
if is_write_supported
|
315
|
+
# 2. If all servers support secondary writes, we respect read preference.
|
316
|
+
suitable_servers(cluster)
|
317
|
+
else
|
318
|
+
# 3. Otherwise we fallback to primary for replica set.
|
319
|
+
[cluster.servers.detect(&:primary?)]
|
320
|
+
end
|
321
|
+
else
|
322
|
+
suitable_servers(cluster)
|
323
|
+
end
|
298
324
|
|
299
325
|
# This list of servers may be ordered in a specific way
|
300
326
|
# by the selector (e.g. for secondary preferred, the first
|
@@ -133,6 +133,13 @@ module Mongo
|
|
133
133
|
private
|
134
134
|
|
135
135
|
def about_to_expire?(session)
|
136
|
+
# Load balancers spec explicitly requires to ignore the logical session
|
137
|
+
# timeout value.
|
138
|
+
# No rationale is provided as of the time of this writing.
|
139
|
+
if @cluster.load_balanced?
|
140
|
+
return false
|
141
|
+
end
|
142
|
+
|
136
143
|
logical_session_timeout = @cluster.logical_session_timeout
|
137
144
|
|
138
145
|
if logical_session_timeout
|
@@ -142,6 +149,10 @@ module Mongo
|
|
142
149
|
end
|
143
150
|
|
144
151
|
def prune!
|
152
|
+
# Load balancers spec explicitly requires not to prune sessions.
|
153
|
+
# No rationale is provided as of the time of this writing.
|
154
|
+
return if @cluster.load_balanced?
|
155
|
+
|
145
156
|
while !@queue.empty?
|
146
157
|
if about_to_expire?(@queue[-1])
|
147
158
|
@queue.pop
|
data/lib/mongo/session.rb
CHANGED
@@ -56,10 +56,16 @@ module Mongo
|
|
56
56
|
# - *:mode* -- the read preference as a string or symbol; valid values are
|
57
57
|
# *:primary*, *:primary_preferred*, *:secondary*, *:secondary_preferred*
|
58
58
|
# and *:nearest*.
|
59
|
+
# @option options [ true | false ] :snapshot Set up the session for
|
60
|
+
# snapshot reads.
|
59
61
|
#
|
60
62
|
# @since 2.5.0
|
61
63
|
# @api private
|
62
64
|
def initialize(server_session, client, options = {})
|
65
|
+
if options[:causal_consistency] && options[:snapshot]
|
66
|
+
raise ArgumentError, ':causal_consistency and :snapshot options cannot be both set on a session'
|
67
|
+
end
|
68
|
+
|
63
69
|
@server_session = server_session
|
64
70
|
options = options.dup
|
65
71
|
|
@@ -83,6 +89,12 @@ module Mongo
|
|
83
89
|
@client.cluster
|
84
90
|
end
|
85
91
|
|
92
|
+
# @return [ true | false ] Whether the session is configured for snapshot
|
93
|
+
# reads.
|
94
|
+
def snapshot?
|
95
|
+
!!options[:snapshot]
|
96
|
+
end
|
97
|
+
|
86
98
|
# @return [ BSON::Timestamp ] The latest seen operation time for this session.
|
87
99
|
#
|
88
100
|
# @since 2.5.0
|
@@ -208,6 +220,12 @@ module Mongo
|
|
208
220
|
# @api private
|
209
221
|
attr_reader :pinned_server
|
210
222
|
|
223
|
+
# @return [ Object | nil ] The service id that this session is pinned to,
|
224
|
+
# if any.
|
225
|
+
#
|
226
|
+
# @api private
|
227
|
+
attr_reader :pinned_service_id
|
228
|
+
|
211
229
|
# @return [ BSON::Document | nil ] Recovery token for the sharded
|
212
230
|
# transaction being executed on this session, if any.
|
213
231
|
#
|
@@ -430,6 +448,7 @@ module Mongo
|
|
430
448
|
transaction_in_progress = false
|
431
449
|
raise
|
432
450
|
end
|
451
|
+
@state = NO_TRANSACTION_STATE
|
433
452
|
next
|
434
453
|
else
|
435
454
|
transaction_in_progress = false
|
@@ -499,6 +518,10 @@ module Mongo
|
|
499
518
|
=end
|
500
519
|
end
|
501
520
|
|
521
|
+
if snapshot?
|
522
|
+
raise Mongo::Error::SnapshotSessionTransactionProhibited
|
523
|
+
end
|
524
|
+
|
502
525
|
check_if_ended!
|
503
526
|
|
504
527
|
if within_states?(STARTING_TRANSACTION_STATE, TRANSACTION_IN_PROGRESS_STATE)
|
@@ -695,7 +718,7 @@ module Mongo
|
|
695
718
|
# @param [ Server ] server The server to pin this session to.
|
696
719
|
#
|
697
720
|
# @api private
|
698
|
-
def
|
721
|
+
def pin_to_server(server)
|
699
722
|
if server.nil?
|
700
723
|
raise ArgumentError, 'Cannot pin to a nil server'
|
701
724
|
end
|
@@ -707,11 +730,24 @@ module Mongo
|
|
707
730
|
@pinned_server = server
|
708
731
|
end
|
709
732
|
|
733
|
+
# Pins this session to the specified service.
|
734
|
+
#
|
735
|
+
# @param [ Object ] service_id The service id to pin this session to.
|
736
|
+
#
|
737
|
+
# @api private
|
738
|
+
def pin_to_service(service_id)
|
739
|
+
if service_id.nil?
|
740
|
+
raise ArgumentError, 'Cannot pin to a nil service id'
|
741
|
+
end
|
742
|
+
@pinned_service_id = service_id
|
743
|
+
end
|
744
|
+
|
710
745
|
# Unpins this session from the pinned server, if the session was pinned.
|
711
746
|
#
|
712
747
|
# @api private
|
713
748
|
def unpin
|
714
749
|
@pinned_server = nil
|
750
|
+
@pinned_service_id = nil
|
715
751
|
end
|
716
752
|
|
717
753
|
# Unpins this session from the pinned server, if the session was pinned
|
@@ -1004,6 +1040,9 @@ module Mongo
|
|
1004
1040
|
@server_session.txn_num
|
1005
1041
|
end
|
1006
1042
|
|
1043
|
+
# @api private
|
1044
|
+
attr_accessor :snapshot_timestamp
|
1045
|
+
|
1007
1046
|
private
|
1008
1047
|
|
1009
1048
|
# Get the read concern the session will use when starting a transaction.
|
@@ -21,8 +21,7 @@ module Mongo
|
|
21
21
|
# This module caches OCSP responses for their indicated validity time.
|
22
22
|
#
|
23
23
|
# The key is the CertificateId used for the OCSP request.
|
24
|
-
# The value is the SingleResponse
|
25
|
-
# emulation of it on Ruby 2.3.
|
24
|
+
# The value is the SingleResponse.
|
26
25
|
#
|
27
26
|
# @api private
|
28
27
|
module OcspCache
|
@@ -40,7 +39,7 @@ module Mongo
|
|
40
39
|
# expire by the time caller uses them. The caller should not perform
|
41
40
|
# update time checks on the returned response.
|
42
41
|
#
|
43
|
-
# @return [ OpenSSL::OCSP::SingleResponse
|
42
|
+
# @return [ OpenSSL::OCSP::SingleResponse ] The previously
|
44
43
|
# retrieved response.
|
45
44
|
module_function def get(cert_id)
|
46
45
|
resp = responses.detect do |resp|
|
@@ -237,43 +237,12 @@ module Mongo
|
|
237
237
|
return false
|
238
238
|
end
|
239
239
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
class << resp
|
247
|
-
attr_reader :uri, :original_uri
|
248
|
-
end
|
249
|
-
else
|
250
|
-
# Ruby 2.3
|
251
|
-
found = nil
|
252
|
-
resp.status.each do |_cert_id, cert_status, revocation_reason, revocation_time, this_update, next_update, extensions|
|
253
|
-
if _cert_id.cmp(cert_id)
|
254
|
-
found = OpenStruct.new(
|
255
|
-
cert_status: cert_status,
|
256
|
-
certid: _cert_id,
|
257
|
-
next_update: next_update,
|
258
|
-
this_update: this_update,
|
259
|
-
revocation_reason: revocation_reason,
|
260
|
-
revocation_time: revocation_time,
|
261
|
-
extensions: extensions,
|
262
|
-
uri: uri,
|
263
|
-
original_uri: original_uri,
|
264
|
-
)
|
265
|
-
class << found
|
266
|
-
# Unlike the stdlib method, this one doesn't accept
|
267
|
-
# any arguments.
|
268
|
-
def check_validity
|
269
|
-
now = Time.now
|
270
|
-
this_update <= now && next_update >= now
|
271
|
-
end
|
272
|
-
end
|
273
|
-
break
|
274
|
-
end
|
275
|
-
end
|
276
|
-
resp = found
|
240
|
+
resp = resp.find_response(cert_id)
|
241
|
+
# TODO make a new class instead of patching the stdlib one?
|
242
|
+
resp.instance_variable_set('@uri', uri)
|
243
|
+
resp.instance_variable_set('@original_uri', original_uri)
|
244
|
+
class << resp
|
245
|
+
attr_reader :uri, :original_uri
|
277
246
|
end
|
278
247
|
|
279
248
|
unless resp
|
data/lib/mongo/socket.rb
CHANGED
@@ -362,11 +362,7 @@ module Mongo
|
|
362
362
|
end
|
363
363
|
|
364
364
|
def allocate_string(capacity)
|
365
|
-
|
366
|
-
String.new('', :capacity => capacity, :encoding => 'BINARY')
|
367
|
-
else
|
368
|
-
('x'*capacity).force_encoding('BINARY')
|
369
|
-
end
|
365
|
+
String.new('', :capacity => capacity, :encoding => 'BINARY')
|
370
366
|
end
|
371
367
|
|
372
368
|
def read_buffer_size
|
@@ -268,6 +268,7 @@ module Mongo
|
|
268
268
|
# Topology options
|
269
269
|
uri_option 'directConnection', :direct_connection, type: :bool
|
270
270
|
uri_option 'connect', :connect, type: :symbol
|
271
|
+
uri_option 'loadBalanced', :load_balanced, type: :bool
|
271
272
|
|
272
273
|
# Auth Options
|
273
274
|
uri_option 'authSource', :auth_source
|