couchbase 3.8.1 → 3.9.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 +2 -2
- data/ext/CMakeLists.txt +16 -1
- data/ext/cache/cpm/{CPM_0.42.0.cmake → CPM_0.43.1.cmake} +18 -2
- data/ext/cache/extconf_include.rb +6 -6
- data/ext/cache/mozilla-ca-bundle.crt +214 -155
- data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
- data/ext/couchbase/CMakeLists.txt +130 -21
- data/ext/couchbase/cmake/APKBUILD.in +25 -4
- data/ext/couchbase/cmake/Bundler.cmake +143 -34
- data/ext/couchbase/cmake/CPM.cmake +126 -12
- data/ext/couchbase/cmake/Cache.cmake +7 -1
- data/ext/couchbase/cmake/CompilerOptions.cmake +1 -1
- data/ext/couchbase/cmake/CompilerWarnings.cmake +17 -6
- data/ext/couchbase/cmake/GrpcProtobuf.cmake +481 -0
- data/ext/couchbase/cmake/OpenSSL.cmake +10 -3
- data/ext/couchbase/cmake/Packaging.cmake +519 -65
- data/ext/couchbase/cmake/Protostellar.cmake +250 -0
- data/ext/couchbase/cmake/Sanitizers.cmake +61 -50
- data/ext/couchbase/cmake/StaticAnalyzers.cmake +16 -5
- data/ext/couchbase/cmake/TestFramework.cmake +283 -0
- data/ext/couchbase/cmake/TestFrameworkAddTests.cmake +51 -0
- data/ext/couchbase/cmake/Testing.cmake +27 -9
- data/ext/couchbase/cmake/ThirdPartyDependencies.cmake +141 -8
- data/ext/couchbase/cmake/VersionInfo.cmake +50 -0
- data/ext/couchbase/cmake/build_config.hxx.in +2 -1
- data/ext/couchbase/cmake/couchbase-cxx-client.spec.in +101 -23
- data/ext/couchbase/cmake/couchbase_cxx_client_static-config.cmake.in +7 -0
- data/ext/couchbase/cmake/couchbase_cxx_client_static.pc.in +2 -0
- data/ext/couchbase/cmake/gRPC_Generate.cmake +58 -0
- data/ext/couchbase/cmake/protobuf_Generate.cmake +69 -0
- data/ext/couchbase/cmake/require-git-checkout.cmake +25 -0
- data/ext/couchbase/cmake/tarball_glob.txt +49 -0
- data/ext/couchbase/core/agent_group.cxx +0 -8
- data/ext/couchbase/core/agent_group.hxx +0 -4
- data/ext/couchbase/core/analytics_stream.cxx +314 -0
- data/ext/couchbase/core/analytics_stream.hxx +129 -0
- data/ext/couchbase/core/analytics_stream_component.cxx +245 -0
- data/ext/couchbase/core/analytics_stream_component.hxx +67 -0
- data/ext/couchbase/core/app_telemetry_meter.cxx +25 -3
- data/ext/couchbase/core/app_telemetry_meter.hxx +77 -0
- data/ext/couchbase/core/app_telemetry_reporter.cxx +7 -6
- data/ext/couchbase/core/bucket.cxx +381 -87
- data/ext/couchbase/core/bucket.hxx +105 -25
- data/ext/couchbase/core/bucket_unit_test_api.hxx +57 -0
- data/ext/couchbase/core/capella.hxx +91 -0
- data/ext/couchbase/core/cluster.cxx +1554 -398
- data/ext/couchbase/core/cluster.hxx +39 -8
- data/ext/couchbase/core/cluster_agent.cxx +0 -8
- data/ext/couchbase/core/cluster_agent.hxx +0 -4
- data/ext/couchbase/core/cluster_options.hxx +26 -3
- data/ext/couchbase/core/collections_component.cxx +39 -15
- data/ext/couchbase/core/config_profiles.cxx +1 -1
- data/ext/couchbase/core/crud_component.cxx +2 -2
- data/ext/couchbase/core/crud_options.hxx +34 -0
- data/ext/couchbase/core/crypto/cbcrypto.cc +18 -13
- data/ext/couchbase/core/document_id_redaction.hxx +81 -0
- data/ext/couchbase/core/error_context/base_error_context.hxx +7 -6
- data/ext/couchbase/core/error_context/key_value.cxx +25 -2
- data/ext/couchbase/core/error_context/key_value.hxx +60 -33
- data/ext/couchbase/core/error_context/key_value_error_context.hxx +16 -15
- data/ext/couchbase/core/error_context/search.hxx +5 -0
- data/ext/couchbase/core/error_context/search_json.hxx +3 -0
- data/ext/couchbase/core/error_context/subdocument_error_context.hxx +19 -18
- data/ext/couchbase/core/error_context/view.hxx +5 -0
- data/ext/couchbase/core/free_form_http_request.cxx +237 -4
- data/ext/couchbase/core/free_form_http_request.hxx +41 -8
- data/ext/couchbase/core/http_component.cxx +300 -284
- data/ext/couchbase/core/http_component.hxx +0 -4
- data/ext/couchbase/core/impl/analytics.cxx +38 -5
- data/ext/couchbase/core/impl/analytics.hxx +34 -0
- data/ext/couchbase/core/impl/bootstrap_error.hxx +0 -3
- data/ext/couchbase/core/impl/collection.cxx +215 -202
- data/ext/couchbase/core/impl/collection_manager.cxx +1 -1
- data/ext/couchbase/core/impl/dns_srv_tracker.cxx +45 -18
- data/ext/couchbase/core/impl/error.cxx +22 -2
- data/ext/couchbase/core/impl/internal_analytics_stream_result.hxx +111 -0
- data/ext/couchbase/core/impl/internal_query_stream_result.hxx +110 -0
- data/ext/couchbase/core/impl/invoke_with_node_id.hxx +15 -7
- data/ext/couchbase/core/impl/key_value_error_category.cxx +6 -0
- data/ext/couchbase/core/impl/lookup_in_replica.cxx +10 -10
- data/ext/couchbase/core/impl/lookup_in_replica.hxx +4 -4
- data/ext/couchbase/core/impl/node_id.cxx +49 -13
- data/ext/couchbase/core/impl/observability_recorder.cxx +12 -2
- data/ext/couchbase/core/impl/observe_poll.cxx +63 -23
- data/ext/couchbase/core/impl/public_analytics_stream_result.cxx +372 -0
- data/ext/couchbase/core/impl/public_bucket.cxx +48 -2
- data/ext/couchbase/core/impl/public_cluster.cxx +325 -25
- data/ext/couchbase/core/impl/public_query_stream_result.cxx +380 -0
- data/ext/couchbase/core/impl/public_transaction_get_multi_replicas_from_preferred_server_group_result.cxx +42 -0
- data/ext/couchbase/core/impl/public_transaction_get_multi_result.cxx +42 -0
- data/ext/couchbase/core/impl/query.cxx +76 -7
- data/ext/couchbase/core/impl/query.hxx +36 -0
- data/ext/couchbase/core/impl/query_index_manager.cxx +54 -1
- data/ext/couchbase/core/impl/replica_utils.cxx +101 -0
- data/ext/couchbase/core/impl/replica_utils.hxx +64 -0
- data/ext/couchbase/core/impl/resolve_node_id.hxx +125 -0
- data/ext/couchbase/core/impl/scope.cxx +70 -0
- data/ext/couchbase/core/impl/search.cxx +31 -1
- data/ext/couchbase/core/impl/transactions.cxx +130 -0
- data/ext/couchbase/core/impl/wait_until_ready.cxx +439 -0
- data/ext/couchbase/core/impl/wait_until_ready.hxx +110 -0
- data/ext/couchbase/core/impl/with_bucket_config_or_timeout.hxx +180 -0
- data/ext/couchbase/core/impl/with_cancellation.hxx +11 -3
- data/ext/couchbase/core/io/configuration_belongs_to_session.hxx +66 -0
- data/ext/couchbase/core/io/dns_client.cxx +122 -45
- data/ext/couchbase/core/io/dns_codec.hxx +21 -21
- data/ext/couchbase/core/io/dns_config.cxx +21 -6
- data/ext/couchbase/core/io/http_command.hxx +149 -121
- data/ext/couchbase/core/io/http_error.hxx +107 -0
- data/ext/couchbase/core/io/http_parser.cxx +4 -0
- data/ext/couchbase/core/io/http_session.cxx +606 -154
- data/ext/couchbase/core/io/http_session.hxx +147 -30
- data/ext/couchbase/core/io/http_session_manager.hxx +329 -382
- data/ext/couchbase/core/io/http_streaming_parser.cxx +4 -0
- data/ext/couchbase/core/io/http_streaming_response.cxx +328 -43
- data/ext/couchbase/core/io/http_streaming_response.hxx +37 -3
- data/ext/couchbase/core/io/mcbp_buffer_pool.hxx +122 -0
- data/ext/couchbase/core/io/mcbp_command.hxx +150 -51
- data/ext/couchbase/core/io/mcbp_command_id.hxx +45 -0
- data/ext/couchbase/core/io/mcbp_message.cxx +9 -1
- data/ext/couchbase/core/io/mcbp_message.hxx +19 -0
- data/ext/couchbase/core/io/mcbp_output_queue.hxx +150 -0
- data/ext/couchbase/core/io/mcbp_parser.cxx +24 -7
- data/ext/couchbase/core/io/mcbp_session.cxx +316 -317
- data/ext/couchbase/core/io/mcbp_session.hxx +27 -18
- data/ext/couchbase/core/io/opaque_ring_table.hxx +145 -0
- data/ext/couchbase/core/io/retry_orchestrator.hxx +6 -5
- data/ext/couchbase/core/io/stream_deadline.hxx +50 -0
- data/ext/couchbase/core/io/streams.cxx +275 -14
- data/ext/couchbase/core/io/streams.hxx +53 -0
- data/ext/couchbase/core/logger/logger.cxx +36 -0
- data/ext/couchbase/core/logger/logger.hxx +46 -6
- data/ext/couchbase/core/logger/redaction.hxx +503 -0
- data/ext/couchbase/core/management/eventing_status.hxx +10 -0
- data/ext/couchbase/core/management/eventing_status_json.hxx +4 -0
- data/ext/couchbase/core/mcbp/big_endian.cxx +1 -1
- data/ext/couchbase/core/mcbp/codec.cxx +27 -18
- data/ext/couchbase/core/mcbp/operation_queue.cxx +2 -2
- data/ext/couchbase/core/mcbp/packet.hxx +2 -2
- data/ext/couchbase/core/mcbp/queue_request.cxx +23 -6
- data/ext/couchbase/core/mcbp/queue_request.hxx +21 -0
- data/ext/couchbase/core/meta/features.hxx +13 -0
- data/ext/couchbase/core/meta/version.cxx +6 -3
- data/ext/couchbase/core/metrics/logging_meter.cxx +5 -10
- data/ext/couchbase/core/metrics/meter_wrapper.cxx +63 -33
- data/ext/couchbase/core/metrics/meter_wrapper.hxx +55 -3
- data/ext/couchbase/core/operations/analytics_response_parsing.cxx +177 -0
- data/ext/couchbase/core/operations/analytics_response_parsing.hxx +55 -0
- data/ext/couchbase/core/operations/document_analytics.cxx +48 -130
- data/ext/couchbase/core/operations/document_analytics.hxx +14 -2
- data/ext/couchbase/core/operations/document_get_all_replicas.hxx +15 -7
- data/ext/couchbase/core/operations/document_get_any_replica.hxx +19 -8
- data/ext/couchbase/core/operations/document_get_projected.cxx +1 -1
- data/ext/couchbase/core/{impl/get_replica.cxx → operations/document_get_replica.cxx} +21 -3
- data/ext/couchbase/core/{impl/get_replica.hxx → operations/document_get_replica.hxx} +31 -4
- data/ext/couchbase/core/operations/document_lookup_in.cxx +10 -10
- data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +228 -198
- data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +215 -217
- data/ext/couchbase/core/operations/document_query.cxx +108 -221
- data/ext/couchbase/core/operations/document_query.hxx +18 -4
- data/ext/couchbase/core/operations/document_search.cxx +52 -8
- data/ext/couchbase/core/operations/document_search.hxx +3 -0
- data/ext/couchbase/core/operations/document_view.cxx +3 -3
- data/ext/couchbase/core/operations/management/analytics_dataset_create.cxx +15 -8
- data/ext/couchbase/core/operations/management/analytics_dataset_create.hxx +4 -0
- data/ext/couchbase/core/operations/management/analytics_dataset_drop.cxx +11 -6
- data/ext/couchbase/core/operations/management/analytics_dataset_get_all.cxx +3 -2
- data/ext/couchbase/core/operations/management/analytics_dataverse_create.cxx +10 -5
- data/ext/couchbase/core/operations/management/analytics_dataverse_drop.cxx +10 -5
- data/ext/couchbase/core/operations/management/analytics_get_pending_mutations.cxx +2 -1
- data/ext/couchbase/core/operations/management/analytics_index_create.cxx +33 -8
- data/ext/couchbase/core/operations/management/analytics_index_drop.cxx +12 -7
- data/ext/couchbase/core/operations/management/analytics_index_get_all.cxx +3 -2
- data/ext/couchbase/core/operations/management/analytics_link_connect.cxx +11 -6
- data/ext/couchbase/core/operations/management/analytics_link_create.cxx +3 -3
- data/ext/couchbase/core/operations/management/analytics_link_disconnect.cxx +10 -4
- data/ext/couchbase/core/operations/management/analytics_link_drop.cxx +6 -4
- data/ext/couchbase/core/operations/management/analytics_link_get_all.cxx +4 -3
- data/ext/couchbase/core/operations/management/analytics_link_replace.cxx +3 -3
- data/ext/couchbase/core/operations/management/analytics_link_utils.hxx +1 -1
- data/ext/couchbase/core/operations/management/bucket_create.cxx +37 -38
- data/ext/couchbase/core/operations/management/bucket_update.cxx +26 -28
- data/ext/couchbase/core/operations/management/change_password.cxx +2 -0
- data/ext/couchbase/core/operations/management/collection_drop.cxx +5 -1
- data/ext/couchbase/core/operations/management/error_utils.cxx +59 -5
- data/ext/couchbase/core/operations/management/error_utils.hxx +29 -1
- data/ext/couchbase/core/operations/management/eventing_deploy_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/eventing_drop_function.cxx +8 -3
- data/ext/couchbase/core/operations/management/eventing_get_all_functions.cxx +4 -2
- data/ext/couchbase/core/operations/management/eventing_get_function.cxx +5 -3
- data/ext/couchbase/core/operations/management/eventing_get_status.cxx +4 -2
- data/ext/couchbase/core/operations/management/eventing_pause_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/eventing_resume_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/eventing_undeploy_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/eventing_upsert_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/group_drop.cxx +3 -1
- data/ext/couchbase/core/operations/management/group_get.cxx +3 -1
- data/ext/couchbase/core/operations/management/group_upsert.cxx +11 -8
- data/ext/couchbase/core/operations/management/query_index_build.cxx +5 -2
- data/ext/couchbase/core/operations/management/query_index_create.cxx +9 -3
- data/ext/couchbase/core/operations/management/query_index_drop.cxx +11 -4
- data/ext/couchbase/core/operations/management/query_index_get_all.cxx +1 -1
- data/ext/couchbase/core/operations/management/query_index_get_all_deferred.cxx +1 -1
- data/ext/couchbase/core/operations/management/scope_drop.cxx +5 -1
- data/ext/couchbase/core/operations/management/scope_get_all.cxx +6 -1
- data/ext/couchbase/core/operations/management/search_get_stats.cxx +10 -0
- data/ext/couchbase/core/operations/management/search_index_analyze_document.cxx +3 -2
- data/ext/couchbase/core/operations/management/search_index_control_ingest.cxx +4 -3
- data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.cxx +4 -3
- data/ext/couchbase/core/operations/management/search_index_control_query.cxx +4 -3
- data/ext/couchbase/core/operations/management/search_index_drop.cxx +2 -2
- data/ext/couchbase/core/operations/management/search_index_get.cxx +2 -2
- data/ext/couchbase/core/operations/management/search_index_get_documents_count.cxx +3 -2
- data/ext/couchbase/core/operations/management/search_index_get_stats.cxx +3 -1
- data/ext/couchbase/core/operations/management/search_index_upsert.cxx +2 -2
- data/ext/couchbase/core/operations/management/user_drop.cxx +3 -1
- data/ext/couchbase/core/operations/management/user_get.cxx +3 -1
- data/ext/couchbase/core/operations/management/user_upsert.cxx +12 -9
- data/ext/couchbase/core/operations/management/view_index_drop.cxx +1 -1
- data/ext/couchbase/core/operations/management/view_index_get.cxx +1 -1
- data/ext/couchbase/core/operations/management/view_index_upsert.cxx +1 -1
- data/ext/couchbase/core/operations/operation_traits.hxx +18 -0
- data/ext/couchbase/core/operations/query_response_parsing.cxx +211 -0
- data/ext/couchbase/core/operations/query_response_parsing.hxx +60 -0
- data/ext/couchbase/core/operations_fwd.hxx +3 -3
- data/ext/couchbase/core/origin.cxx +54 -26
- data/ext/couchbase/core/origin.hxx +12 -0
- data/ext/couchbase/core/orphan_reporter.cxx +2 -1
- data/ext/couchbase/core/platform/random.cc +7 -7
- data/ext/couchbase/core/protocol/client_request.cxx +2 -2
- data/ext/couchbase/core/protocol/client_request.hxx +38 -21
- data/ext/couchbase/core/protocol/client_response.cxx +11 -3
- data/ext/couchbase/core/protocol/client_response.hxx +27 -6
- data/ext/couchbase/core/protocol/cmd_append.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_cluster_map_change_notification.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_decrement.cxx +6 -6
- data/ext/couchbase/core/protocol/cmd_get.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_get_and_lock.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_get_and_touch.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_get_cluster_config.cxx +6 -4
- data/ext/couchbase/core/protocol/cmd_get_collection_id.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_get_error_map.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_get_meta.cxx +4 -4
- data/ext/couchbase/core/protocol/cmd_get_replica.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_hello.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_increment.cxx +6 -6
- data/ext/couchbase/core/protocol/cmd_insert.cxx +4 -4
- data/ext/couchbase/core/protocol/cmd_lookup_in.cxx +4 -3
- data/ext/couchbase/core/protocol/cmd_lookup_in_replica.cxx +4 -3
- data/ext/couchbase/core/protocol/cmd_mutate_in.cxx +10 -9
- data/ext/couchbase/core/protocol/cmd_mutate_in.hxx +10 -10
- data/ext/couchbase/core/protocol/cmd_observe_seqno.cxx +7 -7
- data/ext/couchbase/core/protocol/cmd_prepend.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_remove.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_replace.cxx +4 -4
- data/ext/couchbase/core/protocol/cmd_touch.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_upsert.cxx +4 -4
- data/ext/couchbase/core/protocol/datatype.hxx +118 -1
- data/ext/couchbase/core/protocol/frame_info_utils.cxx +1 -1
- data/ext/couchbase/core/protocol/magic.hxx +4 -0
- data/ext/couchbase/core/protocol/magic_fmt.hxx +3 -0
- data/ext/couchbase/core/protocol/server_request.hxx +3 -1
- data/ext/couchbase/core/protocol/status.cxx +1 -1
- data/ext/couchbase/core/protostellar/analytics_converter.hxx +171 -0
- data/ext/couchbase/core/protostellar/bucket_admin_converter.hxx +301 -0
- data/ext/couchbase/core/protostellar/collection_admin_converter.hxx +92 -0
- data/ext/couchbase/core/protostellar/component.cxx +2445 -0
- data/ext/couchbase/core/protostellar/component.hxx +391 -0
- data/ext/couchbase/core/{columnar/bootstrap_notification_subscriber.hxx → protostellar/compression_settings.hxx} +11 -10
- data/ext/couchbase/core/protostellar/credentials.cxx +233 -0
- data/ext/couchbase/core/protostellar/credentials.hxx +88 -0
- data/ext/couchbase/core/protostellar/dispatcher.cxx +57 -0
- data/ext/couchbase/core/protostellar/dispatcher.hxx +482 -0
- data/ext/couchbase/core/protostellar/error_utils.cxx +293 -0
- data/ext/couchbase/core/protostellar/error_utils.hxx +97 -0
- data/ext/couchbase/core/protostellar/json_payload.hxx +49 -0
- data/ext/couchbase/core/protostellar/kv_converter.cxx +70 -0
- data/ext/couchbase/core/protostellar/kv_converter.hxx +600 -0
- data/ext/couchbase/core/protostellar/query_converter.hxx +265 -0
- data/ext/couchbase/core/protostellar/query_index_admin_converter.hxx +291 -0
- data/ext/couchbase/core/protostellar/query_proto.hxx +73 -0
- data/ext/couchbase/core/protostellar/search_converter.hxx +244 -0
- data/ext/couchbase/core/protostellar/search_index_admin_converter.hxx +156 -0
- data/ext/couchbase/core/protostellar/view_converter.hxx +158 -0
- data/ext/couchbase/core/query_stream.cxx +447 -0
- data/ext/couchbase/core/query_stream.hxx +141 -0
- data/ext/couchbase/core/query_stream_component.cxx +243 -0
- data/ext/couchbase/core/query_stream_component.hxx +68 -0
- data/ext/couchbase/core/range_scan_load_balancer.cxx +15 -8
- data/ext/couchbase/core/range_scan_orchestrator.cxx +15 -3
- data/ext/couchbase/core/response_handler.hxx +41 -4
- data/ext/couchbase/core/row_streamer.cxx +332 -46
- data/ext/couchbase/core/row_streamer.hxx +31 -1
- data/ext/couchbase/core/row_streamer_options.hxx +55 -0
- data/ext/couchbase/core/sasl/client.h +3 -0
- data/ext/couchbase/core/search_scoring.hxx +66 -0
- data/ext/couchbase/core/stream_error_details.hxx +69 -0
- data/ext/couchbase/core/timeout_defaults.hxx +0 -1
- data/ext/couchbase/core/topology/capabilities.hxx +6 -0
- data/ext/couchbase/core/topology/capabilities_fmt.hxx +3 -0
- data/ext/couchbase/core/topology/configuration.cxx +21 -6
- data/ext/couchbase/core/topology/configuration.hxx +29 -8
- data/ext/couchbase/core/topology/configuration_json.hxx +3 -0
- data/ext/couchbase/core/topology/error_map_json.hxx +3 -1
- data/ext/couchbase/core/tracing/threshold_logging_tracer.cxx +70 -4
- data/ext/couchbase/core/tracing/threshold_logging_tracer.hxx +10 -0
- data/ext/couchbase/core/transactions/active_transaction_record.cxx +0 -34
- data/ext/couchbase/core/transactions/attempt_context_impl.cxx +362 -241
- data/ext/couchbase/core/transactions/attempt_context_impl.hxx +24 -3
- data/ext/couchbase/core/transactions/error_list.hxx +2 -2
- data/ext/couchbase/core/transactions/get_multi_fetch.hxx +160 -0
- data/ext/couchbase/core/transactions/get_multi_orchestrator.cxx +326 -125
- data/ext/couchbase/core/transactions/get_multi_transaction_id.hxx +62 -0
- data/ext/couchbase/core/transactions/internal/atr_entry.hxx +22 -2
- data/ext/couchbase/core/transactions/internal/transaction_context.hxx +2 -2
- data/ext/couchbase/core/transactions/internal/transactions_cleanup.hxx +23 -1
- data/ext/couchbase/core/transactions/internal/utils.hxx +50 -14
- data/ext/couchbase/core/transactions/staged_mutation.cxx +23 -18
- data/ext/couchbase/core/transactions/staged_mutation.hxx +15 -4
- data/ext/couchbase/core/transactions/transaction_context.cxx +55 -40
- data/ext/couchbase/core/transactions/transaction_get_result.hxx +16 -0
- data/ext/couchbase/core/transactions/transactions.cxx +3 -55
- data/ext/couchbase/core/transactions/transactions_cleanup.cxx +194 -66
- data/ext/couchbase/core/transactions/transactions_config.cxx +0 -11
- data/ext/couchbase/core/transactions/utils.cxx +10 -0
- data/ext/couchbase/core/transactions/waitable_op_list.hxx +15 -4
- data/ext/couchbase/core/transactions.hxx +9 -9
- data/ext/couchbase/core/utils/byteswap.hxx +166 -9
- data/ext/couchbase/core/utils/connection_string.cxx +50 -85
- data/ext/couchbase/core/utils/connection_string.hxx +15 -0
- data/ext/couchbase/core/{columnar/backoff_calculator.hxx → utils/deadline.hxx} +13 -13
- data/ext/couchbase/core/utils/duration_parser.cxx +1 -1
- data/ext/couchbase/core/utils/json_streaming_lexer.cxx +48 -5
- data/ext/couchbase/core/utils/json_streaming_lexer.hxx +4 -1
- data/ext/couchbase/core/utils/movable_function.hxx +301 -52
- data/ext/couchbase/core/utils/name_codec.hxx +154 -11
- data/ext/couchbase/core/{columnar/retry_info.hxx → utils/process_id.hxx} +18 -13
- data/ext/couchbase/core/utils/url_codec.cxx +12 -51
- data/ext/couchbase/core/websocket_codec.cxx +3 -29
- data/ext/couchbase/couchbase/analytics_options.hxx +21 -10
- data/ext/couchbase/couchbase/analytics_row.hxx +105 -0
- data/ext/couchbase/couchbase/analytics_stream_result.hxx +266 -0
- data/ext/couchbase/couchbase/boolean_query.hxx +3 -3
- data/ext/couchbase/couchbase/bucket.hxx +57 -0
- data/ext/couchbase/couchbase/cluster.hxx +216 -5
- data/ext/couchbase/{core/columnar/security_options.hxx → couchbase/cluster_state.hxx} +18 -14
- data/ext/couchbase/couchbase/codec/lenient_json_transcoder.hxx +69 -0
- data/ext/couchbase/couchbase/collection.hxx +234 -14
- data/ext/couchbase/couchbase/common_durability_options.hxx +18 -3
- data/ext/couchbase/couchbase/conjunction_query.hxx +1 -1
- data/ext/couchbase/couchbase/create_dataset_analytics_options.hxx +6 -1
- data/ext/couchbase/couchbase/date_range_query.hxx +2 -2
- data/ext/couchbase/couchbase/decrement_options.hxx +1 -1
- data/ext/couchbase/couchbase/disjunction_query.hxx +1 -1
- data/ext/couchbase/couchbase/error.hxx +32 -0
- data/ext/couchbase/couchbase/error_codes.hxx +32 -0
- data/ext/couchbase/couchbase/geo_bounding_box_query.hxx +1 -1
- data/ext/couchbase/couchbase/geo_distance_query.hxx +1 -1
- data/ext/couchbase/couchbase/geo_polygon_query.hxx +1 -1
- data/ext/couchbase/couchbase/get_replica_options.hxx +68 -0
- data/ext/couchbase/couchbase/get_replica_result.hxx +5 -3
- data/ext/couchbase/couchbase/get_replica_strategy.hxx +161 -0
- data/ext/couchbase/couchbase/get_result.hxx +1 -0
- data/ext/couchbase/couchbase/increment_options.hxx +1 -1
- data/ext/couchbase/couchbase/insert_options.hxx +1 -1
- data/ext/couchbase/couchbase/match_phrase_query.hxx +1 -1
- data/ext/couchbase/couchbase/match_query.hxx +1 -1
- data/ext/couchbase/couchbase/mutate_in_options.hxx +3 -3
- data/ext/couchbase/couchbase/network_options.hxx +1 -1
- data/ext/couchbase/couchbase/node_id.hxx +42 -14
- data/ext/couchbase/couchbase/node_id_for_options.hxx +7 -1
- data/ext/couchbase/couchbase/node_ids_options.hxx +8 -2
- data/ext/couchbase/couchbase/numeric_range_query.hxx +1 -1
- data/ext/couchbase/couchbase/phrase_query.hxx +1 -1
- data/ext/couchbase/couchbase/prefix_query.hxx +1 -1
- data/ext/couchbase/couchbase/query_options.hxx +23 -12
- data/ext/couchbase/couchbase/query_row.hxx +111 -0
- data/ext/couchbase/couchbase/query_stream_result.hxx +302 -0
- data/ext/couchbase/couchbase/query_string_query.hxx +3 -3
- data/ext/couchbase/couchbase/regexp_query.hxx +1 -1
- data/ext/couchbase/couchbase/replace_options.hxx +3 -3
- data/ext/couchbase/couchbase/result.hxx +14 -3
- data/ext/couchbase/couchbase/scan_result_item.hxx +1 -0
- data/ext/couchbase/couchbase/scope.hxx +85 -2
- data/ext/couchbase/couchbase/search_options.hxx +58 -8
- data/ext/couchbase/couchbase/search_scoring.hxx +94 -0
- data/ext/couchbase/couchbase/search_scoring_none.hxx +51 -0
- data/ext/couchbase/couchbase/search_scoring_reciprocal_rank_fusion.hxx +88 -0
- data/ext/couchbase/couchbase/search_scoring_relative_score_fusion.hxx +70 -0
- data/ext/couchbase/couchbase/term_range_query.hxx +1 -1
- data/ext/couchbase/couchbase/tracing/request_span.hxx +46 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_result.hxx +23 -21
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_result.hxx +24 -19
- data/ext/couchbase/couchbase/transactions/transaction_get_result.hxx +17 -3
- data/ext/couchbase/couchbase/transactions/transactions_config.hxx +4 -2
- data/ext/couchbase/couchbase/transactions.hxx +27 -18
- data/ext/couchbase/couchbase/upsert_options.hxx +3 -3
- data/ext/couchbase/couchbase/vector_query.hxx +1 -1
- data/ext/couchbase/couchbase/wait_until_ready_options.hxx +111 -0
- data/ext/couchbase/couchbase/wildcard_query.hxx +1 -1
- data/ext/extconf.rb +15 -10
- data/ext/rcb_analytics.cxx +82 -102
- data/ext/rcb_backend.cxx +42 -36
- data/ext/rcb_backend.hxx +2 -0
- data/ext/rcb_buckets.cxx +47 -59
- data/ext/rcb_collections.cxx +42 -52
- data/ext/rcb_crud.cxx +345 -224
- data/ext/rcb_diagnostics.cxx +117 -27
- data/ext/rcb_exceptions.cxx +152 -99
- data/ext/rcb_exceptions.hxx +25 -0
- data/ext/rcb_extras.cxx +18 -19
- data/ext/rcb_hdr_histogram.cxx +19 -4
- data/ext/rcb_logger.cxx +202 -27
- data/ext/rcb_logger.hxx +12 -0
- data/ext/rcb_multi.cxx +40 -40
- data/ext/rcb_observability.cxx +7 -5
- data/ext/rcb_query.cxx +99 -142
- data/ext/rcb_range_scan.cxx +41 -35
- data/ext/rcb_search.cxx +98 -99
- data/ext/rcb_users.cxx +36 -56
- data/ext/rcb_utils.cxx +100 -37
- data/ext/rcb_utils.hxx +287 -33
- data/ext/rcb_version.cxx +1 -1
- data/ext/rcb_views.cxx +55 -51
- data/lib/active_support/cache/couchbase_store.rb +77 -12
- data/lib/couchbase/bucket.rb +20 -0
- data/lib/couchbase/cluster.rb +33 -14
- data/lib/couchbase/collection.rb +36 -1
- data/lib/couchbase/errors.rb +18 -0
- data/lib/couchbase/fork_hooks.rb +16 -7
- data/lib/couchbase/get_replica_strategy.rb +89 -0
- data/lib/couchbase/logger.rb +1 -1
- data/lib/couchbase/management/analytics_index_manager.rb +15 -15
- data/lib/couchbase/management/bucket_manager.rb +6 -6
- data/lib/couchbase/management/collection_manager.rb +6 -6
- data/lib/couchbase/management/query_index_manager.rb +7 -7
- data/lib/couchbase/management/search_index_manager.rb +13 -13
- data/lib/couchbase/management/user_manager.rb +10 -10
- data/lib/couchbase/management/view_index_manager.rb +5 -5
- data/lib/couchbase/options.rb +181 -44
- data/lib/couchbase/protostellar/bucket.rb +4 -0
- data/lib/couchbase/protostellar/cluster.rb +4 -0
- data/lib/couchbase/protostellar/collection.rb +4 -0
- data/lib/couchbase/protostellar/error_handling.rb +2 -1
- data/lib/couchbase/protostellar/request.rb +1 -0
- data/lib/couchbase/protostellar/request_generator/kv.rb +16 -2
- data/lib/couchbase/protostellar/request_generator/search.rb +17 -1
- data/lib/couchbase/protostellar/retry/orchestrator.rb +3 -2
- data/lib/couchbase/protostellar/retry/strategies/fail_fast.rb +33 -0
- data/lib/couchbase/protostellar/retry/strategies.rb +1 -0
- data/lib/couchbase/search_options.rb +95 -6
- data/lib/couchbase/version.rb +1 -1
- metadata +92 -33
- data/ext/0001-fix-build-for-mingw-w64-ucrt-x86_64-toolchain.patch +0 -40
- data/ext/couchbase/core/columnar/agent.hxx +0 -71
- data/ext/couchbase/core/columnar/agent_config.hxx +0 -59
- data/ext/couchbase/core/columnar/background_bootstrap_listener.hxx +0 -42
- data/ext/couchbase/core/columnar/backoff_calculator.cxx +0 -62
- data/ext/couchbase/core/columnar/columnar_agent.cxx +0 -147
- data/ext/couchbase/core/columnar/columnar_agent_config.cxx +0 -48
- data/ext/couchbase/core/columnar/columnar_error.cxx +0 -51
- data/ext/couchbase/core/columnar/database_management_options.hxx +0 -56
- data/ext/couchbase/core/columnar/error.hxx +0 -51
- data/ext/couchbase/core/columnar/error_codes.cxx +0 -107
- data/ext/couchbase/core/columnar/error_codes.hxx +0 -75
- data/ext/couchbase/core/columnar/management_component.cxx +0 -300
- data/ext/couchbase/core/columnar/management_component.hxx +0 -56
- data/ext/couchbase/core/columnar/query_component.cxx +0 -523
- data/ext/couchbase/core/columnar/query_component.hxx +0 -57
- data/ext/couchbase/core/columnar/query_options.hxx +0 -59
- data/ext/couchbase/core/columnar/query_result.cxx +0 -130
- data/ext/couchbase/core/columnar/query_result.hxx +0 -78
- data/ext/couchbase/core/io/config_tracker.cxx +0 -687
- data/ext/couchbase/core/io/config_tracker.hxx +0 -123
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
#include <couchbase/build_config.hxx>
|
|
19
|
+
|
|
18
20
|
#include "core/cluster.hxx"
|
|
19
21
|
|
|
20
22
|
#include "analytics.hxx"
|
|
@@ -23,6 +25,7 @@
|
|
|
23
25
|
#include "core/cluster_options.hxx"
|
|
24
26
|
#include "core/core_sdk_shim.hxx"
|
|
25
27
|
#include "core/io/ip_protocol.hxx"
|
|
28
|
+
#include "core/io/streams.hxx"
|
|
26
29
|
#include "core/origin.hxx"
|
|
27
30
|
#include "core/tls_verify_mode.hxx"
|
|
28
31
|
#include "core/tracing/constants.hxx"
|
|
@@ -36,6 +39,7 @@
|
|
|
36
39
|
#include "observability_recorder.hxx"
|
|
37
40
|
#include "query.hxx"
|
|
38
41
|
#include "search.hxx"
|
|
42
|
+
#include "wait_until_ready.hxx"
|
|
39
43
|
|
|
40
44
|
#include <couchbase/analytics_index_manager.hxx>
|
|
41
45
|
#include <couchbase/analytics_options.hxx>
|
|
@@ -46,6 +50,7 @@
|
|
|
46
50
|
#include <couchbase/cluster_options.hxx>
|
|
47
51
|
#include <couchbase/diagnostics_options.hxx>
|
|
48
52
|
#include <couchbase/diagnostics_result.hxx>
|
|
53
|
+
#include <couchbase/error_codes.hxx>
|
|
49
54
|
#include <couchbase/fmt/error.hxx>
|
|
50
55
|
#include <couchbase/fork_event.hxx>
|
|
51
56
|
#include <couchbase/ip_protocol.hxx>
|
|
@@ -65,6 +70,8 @@
|
|
|
65
70
|
#include <asio/execution_context.hpp>
|
|
66
71
|
#include <asio/post.hpp>
|
|
67
72
|
|
|
73
|
+
#include <gsl/assert>
|
|
74
|
+
|
|
68
75
|
#include <functional>
|
|
69
76
|
#include <future>
|
|
70
77
|
#include <memory>
|
|
@@ -173,6 +180,8 @@ options_to_origin(const std::string& connection_string, cluster_options::built o
|
|
|
173
180
|
user_options.server_group = opts.network.server_group;
|
|
174
181
|
|
|
175
182
|
user_options.enable_compression = opts.compression.enabled;
|
|
183
|
+
user_options.compression_min_size = opts.compression.min_size;
|
|
184
|
+
user_options.compression_min_ratio = opts.compression.min_ratio;
|
|
176
185
|
|
|
177
186
|
user_options.enable_metrics = opts.metrics.enabled;
|
|
178
187
|
if (opts.metrics.enabled) {
|
|
@@ -323,6 +332,28 @@ public:
|
|
|
323
332
|
});
|
|
324
333
|
}
|
|
325
334
|
|
|
335
|
+
// The open notify_fork(child) starts and does not wait for. Requests issued meanwhile wait in the
|
|
336
|
+
// core for the bootstrap. A failed open leaves the core closed, so they then get cluster_closed.
|
|
337
|
+
//
|
|
338
|
+
// The handler captures `this`. It runs inline when open() fails or succeeds without I/O, and
|
|
339
|
+
// otherwise on the IO thread before do_close() joins it: do_close() closes the core first, which
|
|
340
|
+
// completes a pending open.
|
|
341
|
+
void reopen()
|
|
342
|
+
{
|
|
343
|
+
opened_future_ = opened_.get_future().share();
|
|
344
|
+
core_.open(options_to_origin(connection_string_, options_), [this](std::error_code ec) {
|
|
345
|
+
if (ec) {
|
|
346
|
+
CB_LOG_ERROR("Unable to reconnect instance after fork: {}", ec.message());
|
|
347
|
+
}
|
|
348
|
+
opened_.set_value();
|
|
349
|
+
});
|
|
350
|
+
// Created now, not after the bootstrap, so transactions() never sees it unset and nothing
|
|
351
|
+
// writes it from the IO thread. The requests its cleanup issues wait in the core for the
|
|
352
|
+
// bootstrap.
|
|
353
|
+
transactions_ =
|
|
354
|
+
std::make_shared<core::transactions::transactions>(core_, options_.transactions);
|
|
355
|
+
}
|
|
356
|
+
|
|
326
357
|
void query(std::string statement, query_options::built options, query_handler&& handler) const
|
|
327
358
|
{
|
|
328
359
|
auto obs_rec = create_observability_recorder(
|
|
@@ -339,6 +370,22 @@ public:
|
|
|
339
370
|
});
|
|
340
371
|
}
|
|
341
372
|
|
|
373
|
+
void query_stream(std::string statement,
|
|
374
|
+
query_options::built options,
|
|
375
|
+
query_stream_handler&& handler) const
|
|
376
|
+
{
|
|
377
|
+
// Instrument the streaming operation exactly like the buffered query(): build the recorder,
|
|
378
|
+
// thread its operation span into the request as parent_span, and hand the recorder to the
|
|
379
|
+
// stream so it finishes (latency metric + span end) at the terminal.
|
|
380
|
+
auto obs_rec = create_observability_recorder(
|
|
381
|
+
core::tracing::operation::query, core::service_type::query, options.parent_span);
|
|
382
|
+
obs_rec->with_query_statement(statement, options);
|
|
383
|
+
auto request = core::impl::build_query_request(
|
|
384
|
+
std::move(statement), {}, std::move(options), obs_rec->operation_span());
|
|
385
|
+
core::impl::dispatch_query_stream(
|
|
386
|
+
core_, std::move(request), std::move(obs_rec), std::move(handler));
|
|
387
|
+
}
|
|
388
|
+
|
|
342
389
|
void analytics_query(std::string statement,
|
|
343
390
|
analytics_options::built options,
|
|
344
391
|
analytics_handler&& handler) const
|
|
@@ -357,10 +404,36 @@ public:
|
|
|
357
404
|
});
|
|
358
405
|
}
|
|
359
406
|
|
|
407
|
+
void analytics_query_stream(std::string statement,
|
|
408
|
+
analytics_options::built options,
|
|
409
|
+
analytics_stream_handler&& handler) const
|
|
410
|
+
{
|
|
411
|
+
// Instrument the streaming operation exactly like the buffered analytics_query() (see
|
|
412
|
+
// query_stream above for the recorder lifetime).
|
|
413
|
+
auto obs_rec = create_observability_recorder(
|
|
414
|
+
core::tracing::operation::analytics, core::service_type::analytics, options.parent_span);
|
|
415
|
+
obs_rec->with_query_statement(statement, options);
|
|
416
|
+
auto request = core::impl::build_analytics_request(
|
|
417
|
+
std::move(statement), std::move(options), {}, {}, obs_rec->operation_span());
|
|
418
|
+
core::impl::dispatch_analytics_stream(
|
|
419
|
+
core_, std::move(request), std::move(obs_rec), std::move(handler));
|
|
420
|
+
}
|
|
421
|
+
|
|
360
422
|
void ping(const ping_options::built& options, ping_handler&& handler) const
|
|
361
423
|
{
|
|
362
424
|
auto obs_rec = create_observability_recorder(
|
|
363
425
|
core::tracing::operation::ping, std::nullopt, options.parent_span);
|
|
426
|
+
#ifdef COUCHBASE_CXX_CLIENT_BUILD_COUCHBASE2
|
|
427
|
+
if (core_.is_protostellar()) {
|
|
428
|
+
// couchbase2 is a thin gRPC client with no per-service sessions to actively probe, and RFC 77
|
|
429
|
+
// defines no ping semantics for it. Mirror Java/Go/.NET, which surface ping as
|
|
430
|
+
// feature_not_available on this protocol, rather than returning a misleading empty report.
|
|
431
|
+
obs_rec->finish(errc::common::feature_not_available);
|
|
432
|
+
return handler(error{ errc::common::feature_not_available,
|
|
433
|
+
"ping is not supported over the couchbase2 protocol" },
|
|
434
|
+
{});
|
|
435
|
+
}
|
|
436
|
+
#endif
|
|
364
437
|
return core_.ping(
|
|
365
438
|
options.report_id,
|
|
366
439
|
{},
|
|
@@ -376,6 +449,16 @@ public:
|
|
|
376
449
|
{
|
|
377
450
|
auto obs_rec = create_observability_recorder(
|
|
378
451
|
core::tracing::operation::diagnostics, std::nullopt, options.parent_span);
|
|
452
|
+
#ifdef COUCHBASE_CXX_CLIENT_BUILD_COUCHBASE2
|
|
453
|
+
if (core_.is_protostellar()) {
|
|
454
|
+
// No per-service sessions exist to report on over couchbase2, and the RFC 77 Diagnostics
|
|
455
|
+
// section is empty. Mirror Java/Go/.NET (feature_not_available) instead of an empty report.
|
|
456
|
+
obs_rec->finish(errc::common::feature_not_available);
|
|
457
|
+
return handler(error{ errc::common::feature_not_available,
|
|
458
|
+
"diagnostics is not supported over the couchbase2 protocol" },
|
|
459
|
+
{});
|
|
460
|
+
}
|
|
461
|
+
#endif
|
|
379
462
|
return core_.diagnostics(
|
|
380
463
|
options.report_id,
|
|
381
464
|
[obs_rec = std::move(obs_rec), handler = std::move(handler)](const auto& resp) mutable {
|
|
@@ -384,6 +467,20 @@ public:
|
|
|
384
467
|
});
|
|
385
468
|
}
|
|
386
469
|
|
|
470
|
+
void wait_until_ready(std::chrono::milliseconds timeout,
|
|
471
|
+
const wait_until_ready_options::built& options,
|
|
472
|
+
wait_until_ready_handler&& handler) const
|
|
473
|
+
{
|
|
474
|
+
return core::impl::wait_until_ready(core_,
|
|
475
|
+
std::nullopt,
|
|
476
|
+
timeout,
|
|
477
|
+
options.desired_state,
|
|
478
|
+
core::impl::to_core_service_types(options.service_types),
|
|
479
|
+
[handler = std::move(handler)](std::error_code ec) mutable {
|
|
480
|
+
return handler(couchbase::error{ ec });
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
|
|
387
484
|
void search(std::string index_name,
|
|
388
485
|
couchbase::search_request request,
|
|
389
486
|
const search_options::built& options,
|
|
@@ -414,19 +511,124 @@ public:
|
|
|
414
511
|
|
|
415
512
|
void notify_fork(fork_event event)
|
|
416
513
|
{
|
|
514
|
+
// asio requires notify_fork() to run with no thread inside io_context::run():
|
|
515
|
+
//
|
|
516
|
+
// "This function must not be called while any other execution_context
|
|
517
|
+
// function, or any function on an I/O object associated with the
|
|
518
|
+
// execution_context, is being called in another thread."
|
|
519
|
+
// -- asio/execution_context.hpp
|
|
520
|
+
//
|
|
521
|
+
// That is not a formality for fork_child: epoll_reactor::notify_fork() closes
|
|
522
|
+
// and recreates epoll_fd_, timer_fd_ and the interrupter, then rewrites every
|
|
523
|
+
// descriptor registration. Running it against a live reactor makes the IO
|
|
524
|
+
// thread epoll_wait() on a descriptor another thread is closing, and then
|
|
525
|
+
// dereference whatever epoll reports as a descriptor_state.
|
|
526
|
+
//
|
|
527
|
+
// So the fixup goes in the window where the IO thread is not running: after
|
|
528
|
+
// the join in fork_prepare, and before the restart that starts the new one.
|
|
417
529
|
if (event == fork_event::prepare) {
|
|
530
|
+
// Quiesce the transactions cleanup threads BEFORE stopping the io_context.
|
|
531
|
+
// transactions_cleanup::stop() joins workers that may be blocking on a KV
|
|
532
|
+
// operation, and only the IO thread can complete those -- so stopping the
|
|
533
|
+
// io_context first can leave that join waiting forever.
|
|
534
|
+
if (transactions_) {
|
|
535
|
+
transactions_->notify_fork(event);
|
|
536
|
+
}
|
|
418
537
|
io_.stop();
|
|
419
|
-
|
|
538
|
+
// Guarded like do_close() below, and for the same reason: close() already
|
|
539
|
+
// stopped the io_context and joined this thread, so a notify_fork(prepare)
|
|
540
|
+
// afterwards has nothing left to join -- and join() on a thread that is not
|
|
541
|
+
// joinable throws std::system_error, out of a void public API.
|
|
542
|
+
if (io_thread_.joinable()) {
|
|
543
|
+
io_thread_.join();
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// Our own IO thread is gone at this point, checkable in program order
|
|
548
|
+
// rather than only by a sanitizer: fork_prepare has just joined it, and
|
|
549
|
+
// fork_child/fork_parent inherit an already-joined one, because prepare runs
|
|
550
|
+
// before fork() and only the forking thread survives into the child. If a
|
|
551
|
+
// later change moves the restart back above this line, this fires
|
|
552
|
+
// immediately instead of turning into an intermittent use-after-free.
|
|
553
|
+
//
|
|
554
|
+
// The transactions cleanup threads were stopped above, before io_.stop(), so
|
|
555
|
+
// by here the only threads this cluster owned are gone.
|
|
556
|
+
Expects(!io_thread_.joinable());
|
|
557
|
+
|
|
558
|
+
if (event == fork_event::prepare) {
|
|
559
|
+
try {
|
|
560
|
+
io_.notify_fork(fork_event_to_asio(event));
|
|
561
|
+
} catch (...) {
|
|
562
|
+
// Undo everything this prepare did, then report. Returning stopped and threadless
|
|
563
|
+
// would hang ~cluster_impl, which waits on a completion only the IO thread can
|
|
564
|
+
// deliver -- the same hazard as the fork_parent path below. The fork
|
|
565
|
+
// must not go ahead, but the cluster stays usable and destructible.
|
|
566
|
+
//
|
|
567
|
+
// The io_context comes back first: restarting cleanup spawns workers that issue KV
|
|
568
|
+
// operations, and only the IO thread completes those. Restoring cleanup matters as
|
|
569
|
+
// much as restoring the thread -- it was stopped above, and leaving it stopped
|
|
570
|
+
// would silently disable lost-attempts cleanup for the rest of the process while
|
|
571
|
+
// this function claimed the cluster was fine.
|
|
572
|
+
//
|
|
573
|
+
// Note for the caller: do not try to compensate by calling notify_fork(parent)
|
|
574
|
+
// after this throws. Prepare has already been undone here, and that call would
|
|
575
|
+
// find a restarted IO thread and trip the precondition above.
|
|
576
|
+
io_.restart();
|
|
577
|
+
io_thread_ = std::thread{ [&io = io_] {
|
|
578
|
+
io.run();
|
|
579
|
+
} };
|
|
580
|
+
if (transactions_) {
|
|
581
|
+
transactions_->notify_fork(fork_event::parent);
|
|
582
|
+
}
|
|
583
|
+
throw;
|
|
584
|
+
}
|
|
585
|
+
} else if (event == fork_event::parent) {
|
|
586
|
+
io_.restart();
|
|
587
|
+
try {
|
|
588
|
+
io_.notify_fork(fork_event_to_asio(event));
|
|
589
|
+
} catch (...) {
|
|
590
|
+
// A service's notify_fork() threw. The io_context is unusable after that (asio says
|
|
591
|
+
// to destroy it), but destruction itself needs a runner: do_close()
|
|
592
|
+
// waits on a completion only the IO thread can deliver, so returning
|
|
593
|
+
// from here stopped and threadless would hang ~cluster_impl instead of
|
|
594
|
+
// surfacing the failure.
|
|
595
|
+
io_thread_ = std::thread{ [&io = io_] {
|
|
596
|
+
io.run();
|
|
597
|
+
} };
|
|
598
|
+
throw;
|
|
599
|
+
}
|
|
600
|
+
io_thread_ = std::thread{ [&io = io_] {
|
|
601
|
+
io.run();
|
|
602
|
+
} };
|
|
420
603
|
} else {
|
|
421
|
-
//
|
|
604
|
+
// The sockets of this io_context share open file descriptions with the parent, and their
|
|
605
|
+
// pending reads, writes and timers belong to the parent's sessions. The child detaches every
|
|
606
|
+
// registered stream and socket, then runs the inherited core's teardown to completion. The
|
|
607
|
+
// teardown cannot reach the parent's connections through them.
|
|
608
|
+
//
|
|
609
|
+
// close() comes before the fixup. It sets stopped_, so if the fixup throws, ~cluster_impl
|
|
610
|
+
// still completes without a runner.
|
|
611
|
+
std::promise<void> closed;
|
|
612
|
+
auto closed_future = closed.get_future();
|
|
613
|
+
core_.close([closed = std::move(closed)]() mutable {
|
|
614
|
+
closed.set_value();
|
|
615
|
+
});
|
|
616
|
+
// The fixup gives the child its own reactor, and on kqueue it is the only code that repairs
|
|
617
|
+
// kqueue_fd_. It must come before the detach: releasing a socket removes it from the
|
|
618
|
+
// reactor, and until the fixup that reactor is the parent's.
|
|
619
|
+
io_.notify_fork(fork_event_to_asio(event));
|
|
620
|
+
core::io::detach_inherited_sockets(io_);
|
|
422
621
|
io_.restart();
|
|
423
622
|
io_thread_ = std::thread{ [&io = io_] {
|
|
424
623
|
io.run();
|
|
425
624
|
} };
|
|
625
|
+
closed_future.get();
|
|
426
626
|
}
|
|
427
|
-
io_.notify_fork(fork_event_to_asio(event));
|
|
428
627
|
|
|
429
|
-
|
|
628
|
+
// prepare was handled above, before the io_context was stopped. The child does
|
|
629
|
+
// not restart cleanup on this impl: it is about to be replaced, and the
|
|
630
|
+
// replacement starts its own.
|
|
631
|
+
if (event == fork_event::parent && transactions_) {
|
|
430
632
|
transactions_->notify_fork(event);
|
|
431
633
|
}
|
|
432
634
|
}
|
|
@@ -436,6 +638,13 @@ public:
|
|
|
436
638
|
// Spawn new thread to avoid joining IO thread from the same thread
|
|
437
639
|
std::thread([self = shared_from_this(), handler = std::move(handler)]() mutable {
|
|
438
640
|
self->do_close();
|
|
641
|
+
// Drop the reference before signalling completion, not after. handler() is what releases
|
|
642
|
+
// the caller's wait, so anything this thread still owns afterwards outlives that wait. When
|
|
643
|
+
// this is the last reference, releasing it later means ~cluster_impl -- which starts another
|
|
644
|
+
// thread and joins the IO thread -- runs unsynchronised with the caller, and a caller that
|
|
645
|
+
// returns from main() leaves those threads running while static destructors tear down the
|
|
646
|
+
// gRPC and abseil singletons underneath them.
|
|
647
|
+
self.reset();
|
|
439
648
|
handler();
|
|
440
649
|
}).detach();
|
|
441
650
|
}
|
|
@@ -445,14 +654,33 @@ public:
|
|
|
445
654
|
return core_;
|
|
446
655
|
}
|
|
447
656
|
|
|
448
|
-
[[nodiscard]] auto
|
|
657
|
+
[[nodiscard]] auto core_transactions() const
|
|
658
|
+
-> const std::shared_ptr<core::transactions::transactions>&
|
|
449
659
|
{
|
|
450
660
|
return transactions_;
|
|
451
661
|
}
|
|
452
662
|
|
|
663
|
+
[[nodiscard]] auto transactions() const -> std::shared_ptr<transactions::transactions>
|
|
664
|
+
{
|
|
665
|
+
return std::make_shared<transactions::transactions>(transactions_);
|
|
666
|
+
}
|
|
667
|
+
|
|
453
668
|
private:
|
|
454
669
|
void do_close()
|
|
455
670
|
{
|
|
671
|
+
if (opened_future_.valid() &&
|
|
672
|
+
opened_future_.wait_for(std::chrono::seconds::zero()) != std::future_status::ready) {
|
|
673
|
+
// Closing the core fails the pending bootstrap and releases the requests the transactions
|
|
674
|
+
// cleanup holds, so neither wait below runs to bootstrap_timeout. The second core_.close()
|
|
675
|
+
// further down finds the core stopped and returns at once.
|
|
676
|
+
std::promise<void> core_stopped;
|
|
677
|
+
auto f = core_stopped.get_future();
|
|
678
|
+
core_.close([core_stopped = std::move(core_stopped)]() mutable {
|
|
679
|
+
core_stopped.set_value();
|
|
680
|
+
});
|
|
681
|
+
f.get();
|
|
682
|
+
opened_future_.wait();
|
|
683
|
+
}
|
|
456
684
|
if (auto txns = std::move(transactions_); txns != nullptr) {
|
|
457
685
|
// blocks until cleanup is finished
|
|
458
686
|
txns->close();
|
|
@@ -487,7 +715,10 @@ private:
|
|
|
487
715
|
cluster_options::built options_;
|
|
488
716
|
asio::io_context io_{ ASIO_CONCURRENCY_HINT_SAFE };
|
|
489
717
|
core::cluster core_{ io_ };
|
|
490
|
-
std::shared_ptr<core::transactions::transactions> transactions_{ nullptr };
|
|
718
|
+
std::shared_ptr<couchbase::core::transactions::transactions> transactions_{ nullptr };
|
|
719
|
+
// Set by reopen(); fulfilled once its open has finished, either way. do_close() reads it.
|
|
720
|
+
std::promise<void> opened_{};
|
|
721
|
+
std::shared_future<void> opened_future_{};
|
|
491
722
|
std::thread io_thread_{ [&io = io_] {
|
|
492
723
|
io.run();
|
|
493
724
|
} };
|
|
@@ -508,6 +739,19 @@ extract_core_cluster(const couchbase::cluster& cluster) -> const core::cluster&
|
|
|
508
739
|
return reinterpret_cast<const std::shared_ptr<cluster_impl>*>(&cluster)->get()->core();
|
|
509
740
|
}
|
|
510
741
|
|
|
742
|
+
/*
|
|
743
|
+
* This function exists only for usage in the unit tests, and might be removed at any moment.
|
|
744
|
+
* Avoid using it unless it is absolutely necessary.
|
|
745
|
+
*/
|
|
746
|
+
auto
|
|
747
|
+
extract_core_transactions(const couchbase::cluster& cluster)
|
|
748
|
+
-> const std::shared_ptr<core::transactions::transactions>&
|
|
749
|
+
{
|
|
750
|
+
return reinterpret_cast<const std::shared_ptr<cluster_impl>*>(&cluster)
|
|
751
|
+
->get()
|
|
752
|
+
->core_transactions();
|
|
753
|
+
}
|
|
754
|
+
|
|
511
755
|
void
|
|
512
756
|
cluster::query(std::string statement, const query_options& options, query_handler&& handler) const
|
|
513
757
|
{
|
|
@@ -526,6 +770,26 @@ cluster::query(std::string statement, const query_options& options) const
|
|
|
526
770
|
return future;
|
|
527
771
|
}
|
|
528
772
|
|
|
773
|
+
void
|
|
774
|
+
cluster::query_stream(std::string statement,
|
|
775
|
+
const query_options& options,
|
|
776
|
+
query_stream_handler&& handler) const
|
|
777
|
+
{
|
|
778
|
+
return impl_->query_stream(std::move(statement), options.build(), std::move(handler));
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
auto
|
|
782
|
+
cluster::query_stream(std::string statement, const query_options& options) const
|
|
783
|
+
-> std::future<std::pair<error, query_stream_result>>
|
|
784
|
+
{
|
|
785
|
+
auto barrier = std::make_shared<std::promise<std::pair<error, query_stream_result>>>();
|
|
786
|
+
auto future = barrier->get_future();
|
|
787
|
+
query_stream(std::move(statement), options, [barrier](auto err, auto result) {
|
|
788
|
+
barrier->set_value({ std::move(err), std::move(result) });
|
|
789
|
+
});
|
|
790
|
+
return future;
|
|
791
|
+
}
|
|
792
|
+
|
|
529
793
|
void
|
|
530
794
|
cluster::analytics_query(std::string statement,
|
|
531
795
|
const analytics_options& options,
|
|
@@ -546,6 +810,26 @@ cluster::analytics_query(std::string statement, const analytics_options& options
|
|
|
546
810
|
return future;
|
|
547
811
|
}
|
|
548
812
|
|
|
813
|
+
void
|
|
814
|
+
cluster::analytics_query_stream(std::string statement,
|
|
815
|
+
const analytics_options& options,
|
|
816
|
+
analytics_stream_handler&& handler) const
|
|
817
|
+
{
|
|
818
|
+
return impl_->analytics_query_stream(std::move(statement), options.build(), std::move(handler));
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
auto
|
|
822
|
+
cluster::analytics_query_stream(std::string statement, const analytics_options& options) const
|
|
823
|
+
-> std::future<std::pair<error, analytics_stream_result>>
|
|
824
|
+
{
|
|
825
|
+
auto barrier = std::make_shared<std::promise<std::pair<error, analytics_stream_result>>>();
|
|
826
|
+
auto future = barrier->get_future();
|
|
827
|
+
analytics_query_stream(std::move(statement), options, [barrier](auto err, auto result) {
|
|
828
|
+
barrier->set_value({ std::move(err), std::move(result) });
|
|
829
|
+
});
|
|
830
|
+
return future;
|
|
831
|
+
}
|
|
832
|
+
|
|
549
833
|
void
|
|
550
834
|
cluster::ping(const couchbase::ping_options& options, couchbase::ping_handler&& handler) const
|
|
551
835
|
{
|
|
@@ -581,6 +865,26 @@ cluster::diagnostics(const couchbase::diagnostics_options& options) const
|
|
|
581
865
|
return barrier->get_future();
|
|
582
866
|
}
|
|
583
867
|
|
|
868
|
+
void
|
|
869
|
+
cluster::wait_until_ready(std::chrono::milliseconds timeout,
|
|
870
|
+
const couchbase::wait_until_ready_options& options,
|
|
871
|
+
couchbase::wait_until_ready_handler&& handler) const
|
|
872
|
+
{
|
|
873
|
+
return impl_->wait_until_ready(timeout, options.build(), std::move(handler));
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
auto
|
|
877
|
+
cluster::wait_until_ready(std::chrono::milliseconds timeout,
|
|
878
|
+
const couchbase::wait_until_ready_options& options) const
|
|
879
|
+
-> std::future<error>
|
|
880
|
+
{
|
|
881
|
+
auto barrier = std::make_shared<std::promise<error>>();
|
|
882
|
+
wait_until_ready(timeout, options, [barrier](auto err) mutable {
|
|
883
|
+
barrier->set_value(std::move(err));
|
|
884
|
+
});
|
|
885
|
+
return barrier->get_future();
|
|
886
|
+
}
|
|
887
|
+
|
|
584
888
|
void
|
|
585
889
|
cluster::search(std::string index_name,
|
|
586
890
|
search_request request,
|
|
@@ -640,6 +944,16 @@ cluster::connect(const std::string& connection_string,
|
|
|
640
944
|
auto
|
|
641
945
|
cluster::notify_fork(fork_event event) -> void
|
|
642
946
|
{
|
|
947
|
+
#if defined(_WIN32)
|
|
948
|
+
// No fork(2) on Windows, so there is nothing to prepare for or recover from.
|
|
949
|
+
// The function stays part of the API on every platform -- callers, the wrapper
|
|
950
|
+
// SDKs especially, should not have to compile differently per platform -- but
|
|
951
|
+
// here it does nothing. Doing the POSIX work instead would stop and restart the
|
|
952
|
+
// io_context and re-bootstrap the cluster for no reason, and asio's IOCP
|
|
953
|
+
// backend has no notify_fork to apply either.
|
|
954
|
+
(void)event;
|
|
955
|
+
return;
|
|
956
|
+
#else
|
|
643
957
|
if (!impl_) {
|
|
644
958
|
return;
|
|
645
959
|
}
|
|
@@ -648,25 +962,11 @@ cluster::notify_fork(fork_event event) -> void
|
|
|
648
962
|
return;
|
|
649
963
|
}
|
|
650
964
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
auto future = barrier->get_future();
|
|
657
|
-
|
|
658
|
-
new_impl->open([this, barrier, new_impl](const auto& err, const auto& /* c */) {
|
|
659
|
-
if (err.ec()) {
|
|
660
|
-
// TODO(SA): we should fall to background reconnect loop similar to Columnar build
|
|
661
|
-
CB_LOG_ERROR("Unable to reconnect instance after fork: {}", err.ec().message());
|
|
662
|
-
return;
|
|
663
|
-
}
|
|
664
|
-
impl_ = new_impl;
|
|
665
|
-
barrier->set_value();
|
|
666
|
-
});
|
|
667
|
-
|
|
668
|
-
future.get();
|
|
669
|
-
}
|
|
965
|
+
impl_ = std::make_shared<cluster_impl>(impl_->connection_string(), impl_->options());
|
|
966
|
+
// Does not wait for the bootstrap: a cluster whose nodes do not answer would hold the child for
|
|
967
|
+
// the bootstrap timeout. The child has one thread here, so nothing reads impl_ concurrently.
|
|
968
|
+
impl_->reopen();
|
|
969
|
+
#endif
|
|
670
970
|
}
|
|
671
971
|
|
|
672
972
|
void
|