couchbase 3.8.2 → 3.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- 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 +121 -55
- data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
- data/ext/couchbase/CMakeLists.txt +136 -23
- 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 +82 -7
- 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 +1551 -397
- 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 +229 -42
- 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 +1 -2
- 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 +309 -301
- 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 +151 -21
- data/ext/couchbase/core/io/streams.hxx +48 -1
- 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/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 +60 -6
- 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 +108 -63
- data/ext/couchbase/core/transactions/attempt_context_impl.hxx +19 -2
- 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 +165 -72
- 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 +2 -2
- 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 +13 -37
- 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 +183 -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 +33 -1
- 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 +17 -0
- 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 +174 -42
- 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 +91 -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
|
@@ -169,20 +169,21 @@ private:
|
|
|
169
169
|
|
|
170
170
|
class observe_context;
|
|
171
171
|
void
|
|
172
|
-
observe_poll(const
|
|
172
|
+
observe_poll(const std::shared_ptr<observe_context>& ctx);
|
|
173
173
|
|
|
174
174
|
class observe_context : public std::enable_shared_from_this<observe_context>
|
|
175
175
|
{
|
|
176
176
|
public:
|
|
177
|
-
observe_context(
|
|
177
|
+
observe_context(cluster core,
|
|
178
178
|
document_id id,
|
|
179
179
|
mutation_token token,
|
|
180
180
|
std::optional<std::chrono::milliseconds> timeout,
|
|
181
181
|
couchbase::persist_to persist_to,
|
|
182
182
|
couchbase::replicate_to replicate_to,
|
|
183
183
|
observe_handler&& handler)
|
|
184
|
-
: poll_deadline_{
|
|
185
|
-
, poll_backoff_{
|
|
184
|
+
: poll_deadline_{ core.io_context() }
|
|
185
|
+
, poll_backoff_{ core.io_context() }
|
|
186
|
+
, core_{ std::move(core) }
|
|
186
187
|
, id_{ std::move(id) }
|
|
187
188
|
, status_{ std::move(token) }
|
|
188
189
|
, timeout_{ timeout }
|
|
@@ -192,6 +193,38 @@ public:
|
|
|
192
193
|
{
|
|
193
194
|
}
|
|
194
195
|
|
|
196
|
+
observe_context(const observe_context&) = delete;
|
|
197
|
+
observe_context(observe_context&&) = delete;
|
|
198
|
+
auto operator=(const observe_context&) -> observe_context& = delete;
|
|
199
|
+
auto operator=(observe_context&&) -> observe_context& = delete;
|
|
200
|
+
|
|
201
|
+
~observe_context()
|
|
202
|
+
{
|
|
203
|
+
// Fail closed. The context is anchored on the io_context by poll_deadline_ for the whole
|
|
204
|
+
// operation, while the config wait captures a weak_ptr and the seqno requests are cancellable
|
|
205
|
+
// core operations. If the io_context is torn down mid-poll, every continuation is dropped and
|
|
206
|
+
// the context is destroyed here with handler_ still set. Deliver an error so a std::future
|
|
207
|
+
// caller never observes broken_promise and a callback caller never hangs -- this is the
|
|
208
|
+
// backstop for every legacy-durability mutation (persist_to / replicate_to), which routes its
|
|
209
|
+
// handler through the observe poll.
|
|
210
|
+
observe_handler handler{};
|
|
211
|
+
{
|
|
212
|
+
const std::scoped_lock lock(handler_mutex_);
|
|
213
|
+
std::swap(handler_, handler);
|
|
214
|
+
}
|
|
215
|
+
if (handler) {
|
|
216
|
+
try {
|
|
217
|
+
handler(errc::network::cluster_closed);
|
|
218
|
+
} catch (...) { // NOLINT(bugprone-empty-catch)
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
[[nodiscard]] auto core() const -> const cluster&
|
|
224
|
+
{
|
|
225
|
+
return core_;
|
|
226
|
+
}
|
|
227
|
+
|
|
195
228
|
void start()
|
|
196
229
|
{
|
|
197
230
|
poll_deadline_.expires_after(poll_deadline_interval_);
|
|
@@ -294,27 +327,30 @@ public:
|
|
|
294
327
|
on_last_response_ = std::move(handler);
|
|
295
328
|
}
|
|
296
329
|
|
|
297
|
-
void execute(
|
|
330
|
+
void execute()
|
|
298
331
|
{
|
|
299
332
|
auto requests = std::move(requests_);
|
|
300
333
|
status_.reset();
|
|
301
|
-
on_last_response(requests.size(), [
|
|
334
|
+
on_last_response(requests.size(), [weak = weak_from_this()](std::error_code ec) mutable {
|
|
302
335
|
if (ec == asio::error::operation_aborted) {
|
|
303
336
|
return;
|
|
304
337
|
}
|
|
305
|
-
|
|
338
|
+
if (auto ctx = weak.lock()) {
|
|
339
|
+
observe_poll(ctx);
|
|
340
|
+
}
|
|
306
341
|
});
|
|
307
342
|
for (auto&& request : requests) {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
343
|
+
core_.execute(std::move(request),
|
|
344
|
+
[ctx = shared_from_this()](observe_seqno_response&& response) {
|
|
345
|
+
ctx->handle_response(std::move(response));
|
|
346
|
+
});
|
|
312
347
|
}
|
|
313
348
|
}
|
|
314
349
|
|
|
315
350
|
private:
|
|
316
351
|
asio::steady_timer poll_deadline_;
|
|
317
352
|
asio::steady_timer poll_backoff_;
|
|
353
|
+
cluster core_;
|
|
318
354
|
const document_id id_;
|
|
319
355
|
observe_status status_;
|
|
320
356
|
std::optional<std::chrono::milliseconds> timeout_;
|
|
@@ -330,13 +366,22 @@ private:
|
|
|
330
366
|
};
|
|
331
367
|
|
|
332
368
|
void
|
|
333
|
-
observe_poll(const
|
|
369
|
+
observe_poll(const std::shared_ptr<observe_context>& ctx)
|
|
334
370
|
{
|
|
335
371
|
const std::string bucket_name = ctx->bucket_name();
|
|
336
|
-
core
|
|
372
|
+
// Capture a weak_ptr, not the context or a core copy: with_bucket_configuration parks this
|
|
373
|
+
// callback in the core (in the bucket-bootstrap window it is not drained on close). The context
|
|
374
|
+
// is kept alive meanwhile by poll_deadline_ on the io_context, and it owns the core through its
|
|
375
|
+
// core_ member -- capturing either strongly here would form a cycle that survives cluster close
|
|
376
|
+
// and strand the handler.
|
|
377
|
+
ctx->core().with_bucket_configuration(
|
|
337
378
|
bucket_name,
|
|
338
|
-
[
|
|
379
|
+
[weak = std::weak_ptr<observe_context>(ctx)](
|
|
339
380
|
std::error_code ec, const std::shared_ptr<core::topology::configuration>& config) mutable {
|
|
381
|
+
auto ctx = weak.lock();
|
|
382
|
+
if (!ctx) {
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
340
385
|
if (ec) {
|
|
341
386
|
return ctx->finish(ec);
|
|
342
387
|
}
|
|
@@ -360,7 +405,7 @@ observe_poll(const cluster& core, std::shared_ptr<observe_context> ctx)
|
|
|
360
405
|
observe_seqno_request{ replica_id, false, ctx->partition_uuid(), ctx->timeout() });
|
|
361
406
|
}
|
|
362
407
|
}
|
|
363
|
-
ctx->execute(
|
|
408
|
+
ctx->execute();
|
|
364
409
|
});
|
|
365
410
|
}
|
|
366
411
|
} // namespace
|
|
@@ -374,14 +419,9 @@ initiate_observe_poll(const cluster& core,
|
|
|
374
419
|
couchbase::replicate_to replicate_to,
|
|
375
420
|
observe_handler&& handler)
|
|
376
421
|
{
|
|
377
|
-
auto ctx = std::make_shared<observe_context>(
|
|
378
|
-
|
|
379
|
-
std::move(token),
|
|
380
|
-
timeout,
|
|
381
|
-
persist_to,
|
|
382
|
-
replicate_to,
|
|
383
|
-
std::move(handler));
|
|
422
|
+
auto ctx = std::make_shared<observe_context>(
|
|
423
|
+
core, std::move(id), std::move(token), timeout, persist_to, replicate_to, std::move(handler));
|
|
384
424
|
ctx->start();
|
|
385
|
-
return observe_poll(
|
|
425
|
+
return observe_poll(ctx);
|
|
386
426
|
}
|
|
387
427
|
} // namespace couchbase::core::impl
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2026. Couchbase, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include <couchbase/analytics_meta_data.hxx>
|
|
19
|
+
#include <couchbase/analytics_metrics.hxx>
|
|
20
|
+
#include <couchbase/analytics_status.hxx>
|
|
21
|
+
#include <couchbase/analytics_stream_result.hxx>
|
|
22
|
+
#include <couchbase/analytics_warning.hxx>
|
|
23
|
+
#include <couchbase/error_codes.hxx>
|
|
24
|
+
|
|
25
|
+
#include "core/operations/document_analytics.hxx"
|
|
26
|
+
#include "core/utils/binary.hxx"
|
|
27
|
+
|
|
28
|
+
#include "analytics.hxx"
|
|
29
|
+
#include "error.hxx"
|
|
30
|
+
#include "internal_analytics_stream_result.hxx"
|
|
31
|
+
#include "observability_recorder.hxx"
|
|
32
|
+
|
|
33
|
+
#include <future>
|
|
34
|
+
#include <memory>
|
|
35
|
+
#include <mutex>
|
|
36
|
+
#include <optional>
|
|
37
|
+
#include <string>
|
|
38
|
+
#include <system_error>
|
|
39
|
+
#include <utility>
|
|
40
|
+
#include <vector>
|
|
41
|
+
|
|
42
|
+
namespace couchbase
|
|
43
|
+
{
|
|
44
|
+
namespace
|
|
45
|
+
{
|
|
46
|
+
auto
|
|
47
|
+
to_binary(const std::string& s) -> codec::binary
|
|
48
|
+
{
|
|
49
|
+
return core::utils::to_binary(s);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
auto
|
|
53
|
+
build_analytics_meta_data(core::operations::analytics_response::analytics_meta_data meta)
|
|
54
|
+
-> analytics_meta_data
|
|
55
|
+
{
|
|
56
|
+
std::vector<analytics_warning> warnings;
|
|
57
|
+
warnings.reserve(meta.warnings.size());
|
|
58
|
+
for (auto& w : meta.warnings) {
|
|
59
|
+
warnings.emplace_back(w.code, std::move(w.message));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const analytics_metrics metrics{
|
|
63
|
+
meta.metrics.elapsed_time, meta.metrics.execution_time, meta.metrics.result_count,
|
|
64
|
+
meta.metrics.result_size, meta.metrics.processed_objects, meta.metrics.error_count,
|
|
65
|
+
meta.metrics.warning_count,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
std::optional<codec::binary> signature;
|
|
69
|
+
if (meta.signature) {
|
|
70
|
+
signature = to_binary(*meta.signature);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return analytics_meta_data{
|
|
74
|
+
std::move(meta.request_id),
|
|
75
|
+
std::move(meta.client_context_id),
|
|
76
|
+
core::impl::map_analytics_status(meta.status),
|
|
77
|
+
std::move(warnings),
|
|
78
|
+
metrics,
|
|
79
|
+
std::move(signature),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
} // namespace
|
|
83
|
+
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
// internal_analytics_stream_result implementation
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
|
|
88
|
+
internal_analytics_stream_result::internal_analytics_stream_result(
|
|
89
|
+
core::analytics_stream stream,
|
|
90
|
+
std::unique_ptr<core::impl::observability_recorder> obs_rec,
|
|
91
|
+
core::error_context::analytics ctx)
|
|
92
|
+
: stream_{ std::move(stream) }
|
|
93
|
+
, ctx_{ std::move(ctx) }
|
|
94
|
+
, obs_rec_{ std::move(obs_rec) }
|
|
95
|
+
{
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
internal_analytics_stream_result::~internal_analytics_stream_result()
|
|
99
|
+
{
|
|
100
|
+
cancel();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
void
|
|
104
|
+
internal_analytics_stream_result::cancel()
|
|
105
|
+
{
|
|
106
|
+
// Resolve any parked meta_data() futures with a cancellation error so they don't throw
|
|
107
|
+
// broken_promise when the stream is torn down before reaching a natural terminal. Idempotent
|
|
108
|
+
// via terminal_reached_, so a real terminal that already ran is preserved.
|
|
109
|
+
resolve_meta_data(errc::common::request_canceled);
|
|
110
|
+
stream_.cancel();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
auto
|
|
114
|
+
internal_analytics_stream_result::signature() const -> std::optional<codec::binary>
|
|
115
|
+
{
|
|
116
|
+
auto raw = stream_.signature();
|
|
117
|
+
if (!raw) {
|
|
118
|
+
return {};
|
|
119
|
+
}
|
|
120
|
+
return to_binary(*raw);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
void
|
|
124
|
+
internal_analytics_stream_result::resolve_meta_data(std::error_code ec)
|
|
125
|
+
{
|
|
126
|
+
std::pair<error, analytics_meta_data> value;
|
|
127
|
+
if (ec) {
|
|
128
|
+
// Report the terminal against the request's context with whatever the response said stamped on,
|
|
129
|
+
// so a mid-stream failure carries the same detail (statement, service error, endpoint) as one
|
|
130
|
+
// that never started. A cancellation leaves the service error code and message unset, because
|
|
131
|
+
// the service never reported one, but the envelope parsed so far is still reported as the body:
|
|
132
|
+
// it names the request id the service logs are keyed by, and the buffered path likewise reports
|
|
133
|
+
// whatever body it received.
|
|
134
|
+
auto ctx = ctx_;
|
|
135
|
+
ctx.ec = ec;
|
|
136
|
+
core::apply_error_details(ctx, stream_.error_details());
|
|
137
|
+
value.first = core::impl::make_error(ctx);
|
|
138
|
+
}
|
|
139
|
+
auto core_meta = stream_.meta_data();
|
|
140
|
+
if (core_meta) {
|
|
141
|
+
value.second = build_analytics_meta_data(std::move(*core_meta));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
std::vector<std::promise<std::pair<error, analytics_meta_data>>> to_satisfy;
|
|
145
|
+
{
|
|
146
|
+
const std::scoped_lock lk{ meta_mutex_ };
|
|
147
|
+
if (terminal_reached_) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
terminal_reached_ = true;
|
|
151
|
+
terminal_value_ = value;
|
|
152
|
+
to_satisfy = std::move(pending_meta_promises_);
|
|
153
|
+
pending_meta_promises_.clear();
|
|
154
|
+
}
|
|
155
|
+
for (auto& promise : to_satisfy) {
|
|
156
|
+
promise.set_value(value);
|
|
157
|
+
}
|
|
158
|
+
// Reached exactly once (the terminal_reached_ guard above returns on every later call), so the
|
|
159
|
+
// operation is finished here: record the latency metric and end the operation span. ec is the
|
|
160
|
+
// terminal error (falsy on a clean drain, request_canceled on teardown before a natural end).
|
|
161
|
+
if (obs_rec_) {
|
|
162
|
+
obs_rec_->finish(ec);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
auto
|
|
167
|
+
internal_analytics_stream_result::meta_data() -> std::future<std::pair<error, analytics_meta_data>>
|
|
168
|
+
{
|
|
169
|
+
const std::scoped_lock lk{ meta_mutex_ };
|
|
170
|
+
std::promise<std::pair<error, analytics_meta_data>> promise;
|
|
171
|
+
auto future = promise.get_future();
|
|
172
|
+
if (terminal_reached_) {
|
|
173
|
+
promise.set_value(terminal_value_);
|
|
174
|
+
} else {
|
|
175
|
+
pending_meta_promises_.push_back(std::move(promise));
|
|
176
|
+
}
|
|
177
|
+
return future;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
void
|
|
181
|
+
internal_analytics_stream_result::next(analytics_row_handler&& handler)
|
|
182
|
+
{
|
|
183
|
+
{
|
|
184
|
+
// Idempotent terminal: once the stream has ended, re-deliver the terminal (clean end or the
|
|
185
|
+
// terminal error) instead of issuing a pull that would block forever on the drained channel.
|
|
186
|
+
const std::scoped_lock lk{ meta_mutex_ };
|
|
187
|
+
if (terminal_reached_) {
|
|
188
|
+
return handler(terminal_value_.first, std::nullopt);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
bool expected = false;
|
|
192
|
+
if (!pull_in_flight_.compare_exchange_strong(expected, true)) {
|
|
193
|
+
// Enforce the single-outstanding-next() contract instead of racing the single-consumer channel.
|
|
194
|
+
return handler(
|
|
195
|
+
error{ errc::common::invalid_argument, "a previous next() call is still in flight" },
|
|
196
|
+
std::nullopt);
|
|
197
|
+
}
|
|
198
|
+
// Capture a strong self so the object outlives an in-flight pull; dropping the public handle
|
|
199
|
+
// mid-pull would otherwise destroy this object before the channel completion runs (use-after-
|
|
200
|
+
// free). The stream is always owned via shared_ptr (make_shared in dispatch_analytics_stream).
|
|
201
|
+
stream_.next_row([handler = std::move(handler), self = shared_from_this()](
|
|
202
|
+
std::optional<std::string> row, std::error_code ec) mutable {
|
|
203
|
+
if (row.has_value()) {
|
|
204
|
+
// Real row (ec is falsy). Release the pull gate before invoking the handler so it may
|
|
205
|
+
// immediately issue the next pull.
|
|
206
|
+
self->pull_in_flight_.store(false);
|
|
207
|
+
return handler({}, analytics_row{ to_binary(*row) });
|
|
208
|
+
}
|
|
209
|
+
// Terminal (nullopt row): publish the terminal state and intentionally leave pull_in_flight_
|
|
210
|
+
// set. Every later next() is served by the terminal_reached_ guard (idempotent re-delivery) and
|
|
211
|
+
// must never issue another pull onto the drained channel, so the gate is never reopened — this
|
|
212
|
+
// also backstops a caller that violates the single-outstanding-next() contract from a racing
|
|
213
|
+
// thread before terminal_reached_ becomes visible.
|
|
214
|
+
self->resolve_meta_data(ec);
|
|
215
|
+
if (ec) {
|
|
216
|
+
// Deliver the contextual error resolve_meta_data() has just published rather than building a
|
|
217
|
+
// bare one here. This is the first and usually only observation of a mid-stream terminal, so
|
|
218
|
+
// it has to carry the same diagnostics as every later next() (served by the terminal_reached_
|
|
219
|
+
// guard above) and as meta_data(); constructing a fresh error here would report the one case
|
|
220
|
+
// this class exists to describe with an empty context.
|
|
221
|
+
error terminal_error;
|
|
222
|
+
{
|
|
223
|
+
const std::scoped_lock lk{ self->meta_mutex_ };
|
|
224
|
+
terminal_error = self->terminal_value_.first;
|
|
225
|
+
}
|
|
226
|
+
return handler(std::move(terminal_error), {});
|
|
227
|
+
}
|
|
228
|
+
return handler({}, {});
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// ---------------------------------------------------------------------------
|
|
233
|
+
// analytics_stream_result public implementation
|
|
234
|
+
// ---------------------------------------------------------------------------
|
|
235
|
+
|
|
236
|
+
analytics_stream_result::analytics_stream_result(
|
|
237
|
+
std::shared_ptr<internal_analytics_stream_result> internal)
|
|
238
|
+
: internal_{ std::move(internal) }
|
|
239
|
+
{
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
void
|
|
243
|
+
analytics_stream_result::next(analytics_row_handler&& handler) const
|
|
244
|
+
{
|
|
245
|
+
if (!internal_) {
|
|
246
|
+
// Empty handle behaves as an immediately-exhausted stream.
|
|
247
|
+
handler(error{}, std::nullopt);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
return internal_->next(std::move(handler));
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
auto
|
|
254
|
+
analytics_stream_result::next() const -> std::future<std::pair<error, std::optional<analytics_row>>>
|
|
255
|
+
{
|
|
256
|
+
auto barrier = std::make_shared<std::promise<std::pair<error, std::optional<analytics_row>>>>();
|
|
257
|
+
if (!internal_) {
|
|
258
|
+
// Empty handle behaves as an immediately-exhausted stream.
|
|
259
|
+
barrier->set_value({ error{}, std::nullopt });
|
|
260
|
+
return barrier->get_future();
|
|
261
|
+
}
|
|
262
|
+
internal_->next([barrier](const auto& err, const auto& row) mutable {
|
|
263
|
+
barrier->set_value({ err, row });
|
|
264
|
+
});
|
|
265
|
+
return barrier->get_future();
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
auto
|
|
269
|
+
analytics_stream_result::signature() const -> std::optional<codec::binary>
|
|
270
|
+
{
|
|
271
|
+
if (!internal_) {
|
|
272
|
+
return {};
|
|
273
|
+
}
|
|
274
|
+
return internal_->signature();
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
auto
|
|
278
|
+
analytics_stream_result::meta_data() const -> std::future<std::pair<error, analytics_meta_data>>
|
|
279
|
+
{
|
|
280
|
+
if (!internal_) {
|
|
281
|
+
// Empty handle resolves immediately with empty metadata.
|
|
282
|
+
std::promise<std::pair<error, analytics_meta_data>> p;
|
|
283
|
+
p.set_value({ error{}, analytics_meta_data{} });
|
|
284
|
+
return p.get_future();
|
|
285
|
+
}
|
|
286
|
+
return internal_->meta_data();
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
void
|
|
290
|
+
analytics_stream_result::cancel() const
|
|
291
|
+
{
|
|
292
|
+
if (internal_) {
|
|
293
|
+
return internal_->cancel();
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// ---------------------------------------------------------------------------
|
|
298
|
+
// iterator implementation
|
|
299
|
+
// ---------------------------------------------------------------------------
|
|
300
|
+
|
|
301
|
+
analytics_stream_result::iterator::iterator(
|
|
302
|
+
std::shared_ptr<internal_analytics_stream_result> internal)
|
|
303
|
+
: internal_{ std::move(internal) }
|
|
304
|
+
{
|
|
305
|
+
if (internal_) {
|
|
306
|
+
fetch_item();
|
|
307
|
+
} else {
|
|
308
|
+
// An empty result handle has no rows: the iterator starts already at end.
|
|
309
|
+
terminal_ = true;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
void
|
|
314
|
+
analytics_stream_result::iterator::fetch_item()
|
|
315
|
+
{
|
|
316
|
+
auto barrier = std::make_shared<std::promise<std::pair<error, std::optional<analytics_row>>>>();
|
|
317
|
+
internal_->next([barrier](const error& err, std::optional<analytics_row> row) mutable {
|
|
318
|
+
barrier->set_value({ err, std::move(row) });
|
|
319
|
+
});
|
|
320
|
+
auto result = barrier->get_future().get();
|
|
321
|
+
if (result.first) {
|
|
322
|
+
// Terminal error: deliver it as one visible element (still != end()) so a range-for loop can
|
|
323
|
+
// observe it; the next increment then advances to true end.
|
|
324
|
+
item_ = { result.first, {} };
|
|
325
|
+
terminal_ = false;
|
|
326
|
+
error_pending_ = true;
|
|
327
|
+
} else if (!result.second.has_value()) {
|
|
328
|
+
// Clean end-of-stream.
|
|
329
|
+
item_ = {};
|
|
330
|
+
terminal_ = true;
|
|
331
|
+
error_pending_ = false;
|
|
332
|
+
} else {
|
|
333
|
+
item_ = { {}, *result.second };
|
|
334
|
+
terminal_ = false;
|
|
335
|
+
error_pending_ = false;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
auto
|
|
340
|
+
analytics_stream_result::iterator::operator*() const -> std::pair<error, analytics_row>
|
|
341
|
+
{
|
|
342
|
+
return item_;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
auto
|
|
346
|
+
analytics_stream_result::iterator::operator++() -> analytics_stream_result::iterator&
|
|
347
|
+
{
|
|
348
|
+
if (error_pending_) {
|
|
349
|
+
// The terminal error element has been consumed; advance to end().
|
|
350
|
+
error_pending_ = false;
|
|
351
|
+
item_ = {};
|
|
352
|
+
terminal_ = true;
|
|
353
|
+
return *this;
|
|
354
|
+
}
|
|
355
|
+
fetch_item();
|
|
356
|
+
return *this;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
auto
|
|
360
|
+
analytics_stream_result::begin() const -> analytics_stream_result::iterator
|
|
361
|
+
{
|
|
362
|
+
// The iterator constructor treats a null internal handle as an already-drained stream, so an
|
|
363
|
+
// empty result handle yields begin() == end().
|
|
364
|
+
return analytics_stream_result::iterator{ internal_ };
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
auto
|
|
368
|
+
analytics_stream_result::end() const -> analytics_stream_result::end_sentinel
|
|
369
|
+
{
|
|
370
|
+
return {};
|
|
371
|
+
}
|
|
372
|
+
} // namespace couchbase
|
|
@@ -15,21 +15,24 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
#include <couchbase/bucket.hxx>
|
|
19
|
-
|
|
20
18
|
#include "core/cluster.hxx"
|
|
21
19
|
#include "core/tracing/constants.hxx"
|
|
22
20
|
#include "core/tracing/tracer_wrapper.hxx"
|
|
23
21
|
#include "diagnostics.hxx"
|
|
24
22
|
#include "observability_recorder.hxx"
|
|
23
|
+
#include "wait_until_ready.hxx"
|
|
24
|
+
#include <couchbase/bucket.hxx>
|
|
25
|
+
#include <couchbase/build_config.hxx>
|
|
25
26
|
|
|
26
27
|
#include <couchbase/collection.hxx>
|
|
27
28
|
#include <couchbase/collection_manager.hxx>
|
|
28
29
|
#include <couchbase/error.hxx>
|
|
30
|
+
#include <couchbase/error_codes.hxx>
|
|
29
31
|
#include <couchbase/ping_options.hxx>
|
|
30
32
|
#include <couchbase/ping_result.hxx>
|
|
31
33
|
#include <couchbase/scope.hxx>
|
|
32
34
|
|
|
35
|
+
#include <chrono>
|
|
33
36
|
#include <future>
|
|
34
37
|
#include <memory>
|
|
35
38
|
#include <string_view>
|
|
@@ -68,6 +71,15 @@ public:
|
|
|
68
71
|
{
|
|
69
72
|
auto obs_rec = create_observability_recorder(
|
|
70
73
|
core::tracing::operation::ping, std::nullopt, options.parent_span);
|
|
74
|
+
#ifdef COUCHBASE_CXX_CLIENT_BUILD_COUCHBASE2
|
|
75
|
+
if (core_.is_protostellar()) {
|
|
76
|
+
// couchbase2 has no per-bucket sessions to probe; mirror cluster::ping and the other SDKs.
|
|
77
|
+
obs_rec->finish(errc::common::feature_not_available);
|
|
78
|
+
return handler(error{ errc::common::feature_not_available,
|
|
79
|
+
"ping is not supported over the couchbase2 protocol" },
|
|
80
|
+
{});
|
|
81
|
+
}
|
|
82
|
+
#endif
|
|
71
83
|
return core_.ping(
|
|
72
84
|
options.report_id,
|
|
73
85
|
name_,
|
|
@@ -79,6 +91,20 @@ public:
|
|
|
79
91
|
});
|
|
80
92
|
}
|
|
81
93
|
|
|
94
|
+
void wait_until_ready(std::chrono::milliseconds timeout,
|
|
95
|
+
const wait_until_ready_options::built& options,
|
|
96
|
+
wait_until_ready_handler&& handler) const
|
|
97
|
+
{
|
|
98
|
+
return core::impl::wait_until_ready(core_,
|
|
99
|
+
name_,
|
|
100
|
+
timeout,
|
|
101
|
+
options.desired_state,
|
|
102
|
+
core::impl::to_core_service_types(options.service_types),
|
|
103
|
+
[handler = std::move(handler)](std::error_code ec) mutable {
|
|
104
|
+
return handler(couchbase::error{ ec });
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
82
108
|
private:
|
|
83
109
|
[[nodiscard]] auto create_observability_recorder(
|
|
84
110
|
const std::string& operation_name,
|
|
@@ -148,6 +174,26 @@ bucket::ping(const couchbase::ping_options& options) const
|
|
|
148
174
|
return barrier->get_future();
|
|
149
175
|
}
|
|
150
176
|
|
|
177
|
+
void
|
|
178
|
+
bucket::wait_until_ready(std::chrono::milliseconds timeout,
|
|
179
|
+
const couchbase::wait_until_ready_options& options,
|
|
180
|
+
couchbase::wait_until_ready_handler&& handler) const
|
|
181
|
+
{
|
|
182
|
+
return impl_->wait_until_ready(timeout, options.build(), std::move(handler));
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
auto
|
|
186
|
+
bucket::wait_until_ready(std::chrono::milliseconds timeout,
|
|
187
|
+
const couchbase::wait_until_ready_options& options) const
|
|
188
|
+
-> std::future<error>
|
|
189
|
+
{
|
|
190
|
+
auto barrier = std::make_shared<std::promise<error>>();
|
|
191
|
+
wait_until_ready(timeout, options, [barrier](auto err) mutable {
|
|
192
|
+
barrier->set_value(std::move(err));
|
|
193
|
+
});
|
|
194
|
+
return barrier->get_future();
|
|
195
|
+
}
|
|
196
|
+
|
|
151
197
|
auto
|
|
152
198
|
bucket::collections() const -> collection_manager
|
|
153
199
|
{
|