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
|
@@ -16,13 +16,17 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
#include "queue_request.hxx"
|
|
19
|
+
|
|
19
20
|
#include "../operation_map.hxx"
|
|
20
|
-
#include "core/logger/logger.hxx"
|
|
21
21
|
#include "operation_queue.hxx"
|
|
22
22
|
#include "queue_response.hxx"
|
|
23
23
|
|
|
24
24
|
#include <couchbase/error_codes.hxx>
|
|
25
25
|
|
|
26
|
+
#include <spdlog/fmt/bundled/core.h>
|
|
27
|
+
|
|
28
|
+
#include <couchbase/fmt/retry_reason.hxx>
|
|
29
|
+
|
|
26
30
|
#include <atomic>
|
|
27
31
|
|
|
28
32
|
namespace couchbase::core::mcbp
|
|
@@ -127,32 +131,42 @@ void
|
|
|
127
131
|
queue_request::cancel(std::error_code error)
|
|
128
132
|
{
|
|
129
133
|
if (internal_cancel()) {
|
|
130
|
-
callback_
|
|
134
|
+
// Move callback_ before invoking to release any captured state (e.g. shared_ptr cycles)
|
|
135
|
+
// as soon as the callback returns rather than retaining it for the lifetime of the request.
|
|
136
|
+
auto cb = std::move(callback_);
|
|
137
|
+
cb({}, shared_from_this(), error);
|
|
131
138
|
}
|
|
132
139
|
}
|
|
133
140
|
|
|
134
141
|
void
|
|
135
142
|
queue_request::set_deadline(std::shared_ptr<asio::steady_timer> timer)
|
|
136
143
|
{
|
|
144
|
+
const std::scoped_lock lock(processing_mutex_);
|
|
137
145
|
deadline_ = std::move(timer);
|
|
138
146
|
}
|
|
139
147
|
|
|
140
148
|
void
|
|
141
149
|
queue_request::set_retry_backoff(std::shared_ptr<asio::steady_timer> timer)
|
|
142
150
|
{
|
|
151
|
+
const std::scoped_lock lock(processing_mutex_);
|
|
143
152
|
retry_backoff_ = std::move(timer);
|
|
144
153
|
}
|
|
145
154
|
|
|
146
155
|
void
|
|
147
156
|
queue_request::try_callback(std::shared_ptr<queue_response> response, std::error_code error)
|
|
148
157
|
{
|
|
149
|
-
|
|
150
|
-
|
|
158
|
+
{
|
|
159
|
+
const std::scoped_lock lock(processing_mutex_);
|
|
160
|
+
cancel_timer(deadline_);
|
|
161
|
+
cancel_timer(retry_backoff_);
|
|
162
|
+
}
|
|
151
163
|
|
|
152
164
|
if (persistent_) {
|
|
153
165
|
if (error) {
|
|
154
166
|
if (internal_cancel()) {
|
|
155
|
-
|
|
167
|
+
// Move callback_ before invoking to release any captured state (e.g. shared_ptr cycles).
|
|
168
|
+
auto cb = std::move(callback_);
|
|
169
|
+
return cb(std::move(response), shared_from_this(), error);
|
|
156
170
|
}
|
|
157
171
|
} else if (!is_completed_) {
|
|
158
172
|
return callback_(std::move(response), shared_from_this(), error);
|
|
@@ -160,7 +174,10 @@ queue_request::try_callback(std::shared_ptr<queue_response> response, std::error
|
|
|
160
174
|
return;
|
|
161
175
|
}
|
|
162
176
|
if (bool expected_state{ false }; is_completed_.compare_exchange_strong(expected_state, true)) {
|
|
163
|
-
|
|
177
|
+
// Move callback_ before invoking to release any captured state (e.g. shared_ptr cycles)
|
|
178
|
+
// as soon as the callback returns.
|
|
179
|
+
auto cb = std::move(callback_);
|
|
180
|
+
return cb(std::move(response), shared_from_this(), error);
|
|
164
181
|
}
|
|
165
182
|
}
|
|
166
183
|
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
#include <asio/steady_timer.hpp>
|
|
28
28
|
|
|
29
29
|
#include <atomic>
|
|
30
|
+
#include <functional>
|
|
30
31
|
#include <memory>
|
|
31
32
|
#include <mutex>
|
|
32
33
|
#include <set>
|
|
@@ -36,6 +37,11 @@ namespace couchbase::core
|
|
|
36
37
|
class operation_map;
|
|
37
38
|
} // namespace couchbase::core
|
|
38
39
|
|
|
40
|
+
namespace couchbase::tracing
|
|
41
|
+
{
|
|
42
|
+
class request_span;
|
|
43
|
+
} // namespace couchbase::tracing
|
|
44
|
+
|
|
39
45
|
namespace couchbase::core::mcbp
|
|
40
46
|
{
|
|
41
47
|
class operation_queue;
|
|
@@ -73,6 +79,13 @@ public:
|
|
|
73
79
|
std::string collection_name_{};
|
|
74
80
|
std::string scope_name_{};
|
|
75
81
|
std::size_t replica_index_{ 0 };
|
|
82
|
+
|
|
83
|
+
// Set by collections_component when a request is dispatched through the collection-id cache.
|
|
84
|
+
// Invoked by the KV response path on an unknown_collection status to invalidate the cached id,
|
|
85
|
+
// re-resolve it (GetCollectionID) and retry the request. Returns true if a retry was scheduled.
|
|
86
|
+
// Left empty for requests that bypass the cache (e.g. the GetCollectionID resolution requests
|
|
87
|
+
// themselves), which must not recurse.
|
|
88
|
+
std::function<bool()> on_unknown_collection_{};
|
|
76
89
|
// This tracks when the request was dispatched so that we can properly prioritize older requests
|
|
77
90
|
// to try and meet timeout requirements.
|
|
78
91
|
std::chrono::steady_clock::time_point dispatched_time_{};
|
|
@@ -86,6 +99,14 @@ public:
|
|
|
86
99
|
// the request and calculating any back-off time period.
|
|
87
100
|
std::shared_ptr<couchbase::retry_strategy> retry_strategy_{};
|
|
88
101
|
|
|
102
|
+
// The parent tracing span for this operation, set by crud_component before dispatching.
|
|
103
|
+
// Kept alive here so the span outlives any retry loops.
|
|
104
|
+
std::shared_ptr<couchbase::tracing::request_span> parent_span_{ nullptr };
|
|
105
|
+
|
|
106
|
+
// The per-dispatch child span representing a single attempt on a specific node.
|
|
107
|
+
// Reset and recreated on every retry by crud_component.
|
|
108
|
+
std::shared_ptr<couchbase::tracing::request_span> dispatch_span_{ nullptr };
|
|
109
|
+
|
|
89
110
|
private:
|
|
90
111
|
// Static routing properties
|
|
91
112
|
queue_callback callback_;
|
|
@@ -268,3 +268,16 @@
|
|
|
268
268
|
* Support for the stable OpenTelemetry conventions (Observability RFC revisions 26 & 27)
|
|
269
269
|
*/
|
|
270
270
|
#define COUCHBASE_CXX_CLIENT_STABLE_OTEL_CONVENTIONS 1
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* An HTTP 400 that matches no more specific error is reported as
|
|
274
|
+
* couchbase::errc::common::invalid_argument (SDK-RFC 58 revision 22).
|
|
275
|
+
*/
|
|
276
|
+
#define COUCHBASE_CXX_CLIENT_HTTP_400_IS_INVALID_ARGUMENT 1
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* The implementations for couchbase::transactions::transactions and
|
|
280
|
+
* couchbase::core::transactions::transactions are separate, i.e.,
|
|
281
|
+
* couchbase::core::transactions::transactions does not implement the Public API.
|
|
282
|
+
*/
|
|
283
|
+
#define COUCHBASE_CXX_CLIENT_TRANSACTIONS_PUBLIC_CORE_IMPL_SEPARATION 1
|
|
@@ -89,8 +89,11 @@ sdk_build_info() -> std::map<std::string, std::string>
|
|
|
89
89
|
"false"
|
|
90
90
|
#endif
|
|
91
91
|
;
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
// Whether this build can serve couchbase2:// connection strings, i.e. whether it was compiled
|
|
93
|
+
// with Cloud Native Gateway support. A build without it rejects the scheme at connect time, so
|
|
94
|
+
// the answer is worth reporting next to the other build-time switches.
|
|
95
|
+
info["couchbase2"] =
|
|
96
|
+
#if defined(COUCHBASE_CXX_CLIENT_BUILD_COUCHBASE2)
|
|
94
97
|
"true"
|
|
95
98
|
#else
|
|
96
99
|
"false"
|
|
@@ -194,7 +197,7 @@ sdk_build_info_json() -> std::string
|
|
|
194
197
|
name == "version_build" || name == "mozilla_ca_bundle_size") {
|
|
195
198
|
info[name] = std::stoi(value);
|
|
196
199
|
} else if (name == "snapshot" || name == "static_stdlib" || name == "static_openssl" ||
|
|
197
|
-
name == "mozilla_ca_bundle_embedded") {
|
|
200
|
+
name == "couchbase2" || name == "mozilla_ca_bundle_embedded") {
|
|
198
201
|
info[name] = value == "true";
|
|
199
202
|
} else {
|
|
200
203
|
info[name] = value;
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
#include "constants.hxx"
|
|
23
23
|
#include "core/logger/logger.hxx"
|
|
24
|
+
#include "core/logger/redaction.hxx"
|
|
24
25
|
#include "core/tracing/constants.hxx"
|
|
25
26
|
#include "core/utils/json.hxx"
|
|
26
27
|
#include "noop_meter.hxx"
|
|
@@ -161,7 +162,7 @@ logging_meter::log_report() const
|
|
|
161
162
|
}
|
|
162
163
|
}
|
|
163
164
|
if (report.find("operations") != nullptr) {
|
|
164
|
-
CB_LOG_INFO("Metrics: {}", utils::json::generate(report));
|
|
165
|
+
CB_LOG_INFO("Metrics: {}", logger::metadata(utils::json::generate(report)));
|
|
165
166
|
}
|
|
166
167
|
}
|
|
167
168
|
|
|
@@ -228,14 +229,8 @@ logging_meter::get_value_recorder(const std::string& name,
|
|
|
228
229
|
const std::scoped_lock lock(recorders_mutex_);
|
|
229
230
|
auto& service_recorders = recorders_[service->second];
|
|
230
231
|
|
|
231
|
-
auto
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
service_recorders.try_emplace(operation->second,
|
|
237
|
-
std::make_shared<logging_value_recorder>(operation->second, tags));
|
|
238
|
-
recorder = service_recorders.find(operation->second);
|
|
239
|
-
return recorder->second;
|
|
232
|
+
auto [it, _] = service_recorders.try_emplace(
|
|
233
|
+
operation->second, std::make_shared<logging_value_recorder>(operation->second, tags));
|
|
234
|
+
return it->second;
|
|
240
235
|
}
|
|
241
236
|
} // namespace couchbase::core::metrics
|
|
@@ -22,6 +22,9 @@
|
|
|
22
22
|
#include "core/metrics/constants.hxx"
|
|
23
23
|
#include "core/tracing/constants.hxx"
|
|
24
24
|
|
|
25
|
+
#include <algorithm>
|
|
26
|
+
#include <array>
|
|
27
|
+
#include <cctype>
|
|
25
28
|
#include <map>
|
|
26
29
|
#include <memory>
|
|
27
30
|
#include <string>
|
|
@@ -62,23 +65,15 @@ extract_error_name(std::error_code ec) -> std::string
|
|
|
62
65
|
return ec.message();
|
|
63
66
|
}
|
|
64
67
|
|
|
68
|
+
} // namespace
|
|
69
|
+
|
|
65
70
|
auto
|
|
66
|
-
|
|
71
|
+
standardized_error_type(std::error_code ec) -> std::string
|
|
67
72
|
{
|
|
68
73
|
if (!ec) {
|
|
69
74
|
return {};
|
|
70
75
|
}
|
|
71
76
|
|
|
72
|
-
// SDK-specific errors
|
|
73
|
-
if (ec.value() >= 1000) {
|
|
74
|
-
return "CouchbaseError";
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Errors where message and RFC-message don't match
|
|
78
|
-
if (ec == errc::field_level_encryption::generic_cryptography_failure) {
|
|
79
|
-
return "CryptoError";
|
|
80
|
-
}
|
|
81
|
-
|
|
82
77
|
static const std::array<const std::error_category*, 12> cb_categories = {
|
|
83
78
|
&impl::common_category(), &impl::key_value_category(),
|
|
84
79
|
&impl::query_category(), &impl::analytics_category(),
|
|
@@ -88,16 +83,30 @@ get_standardized_error_type(std::error_code ec) -> std::string
|
|
|
88
83
|
&impl::transaction_category(), &impl::transaction_op_category(),
|
|
89
84
|
};
|
|
90
85
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
86
|
+
// Classify only against the Couchbase categories. Numeric error values overlap across the
|
|
87
|
+
// platform/system/asio categories, so a value-based check alone would misclassify a foreign error
|
|
88
|
+
// (e.g. a TLS or system error that happens to have value >= 1000) as a Couchbase error.
|
|
89
|
+
const bool couchbase_error =
|
|
90
|
+
std::any_of(cb_categories.begin(), cb_categories.end(), [&ec](const std::error_category* cat) {
|
|
91
|
+
return &ec.category() == cat;
|
|
92
|
+
});
|
|
93
|
+
if (!couchbase_error) {
|
|
94
|
+
return "_OTHER";
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// The SDK's network errors (couchbase::errc::network) use values >= 1000 and are reported under a
|
|
98
|
+
// single generic bucket rather than by individual name.
|
|
99
|
+
if (ec.value() >= 1000) {
|
|
100
|
+
return "CouchbaseError";
|
|
96
101
|
}
|
|
97
102
|
|
|
98
|
-
|
|
103
|
+
// Errors where message and RFC-message don't match
|
|
104
|
+
if (ec == errc::field_level_encryption::generic_cryptography_failure) {
|
|
105
|
+
return "CryptoError";
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return snake_case_to_camel_case(extract_error_name(ec));
|
|
99
109
|
}
|
|
100
|
-
} // namespace
|
|
101
110
|
|
|
102
111
|
auto
|
|
103
112
|
metric_attributes::encode() const -> std::map<std::string, std::string>
|
|
@@ -124,8 +133,8 @@ metric_attributes::encode() const -> std::map<std::string, std::string>
|
|
|
124
133
|
if (collection_name) {
|
|
125
134
|
tags.emplace(tracing::attributes::op::collection_name, collection_name.value());
|
|
126
135
|
}
|
|
127
|
-
if (
|
|
128
|
-
tags.emplace(tracing::attributes::op::error_type,
|
|
136
|
+
if (!error_type.empty()) {
|
|
137
|
+
tags.emplace(tracing::attributes::op::error_type, error_type);
|
|
129
138
|
}
|
|
130
139
|
|
|
131
140
|
return tags;
|
|
@@ -150,28 +159,49 @@ meter_wrapper::stop()
|
|
|
150
159
|
meter_->stop();
|
|
151
160
|
}
|
|
152
161
|
|
|
153
|
-
|
|
154
|
-
meter_wrapper::
|
|
155
|
-
|
|
162
|
+
auto
|
|
163
|
+
meter_wrapper::value_recorder_for(const metric_attributes& attrs)
|
|
164
|
+
-> std::shared_ptr<couchbase::metrics::value_recorder>
|
|
156
165
|
{
|
|
157
|
-
|
|
166
|
+
{
|
|
167
|
+
const std::scoped_lock lock(recorder_cache_mutex_);
|
|
168
|
+
if (auto it = recorder_cache_.find(attrs); it != recorder_cache_.end()) {
|
|
169
|
+
return it->second;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Resolve outside the lock: encode() and the pluggable meter's get_value_recorder() are
|
|
174
|
+
// user-visible code paths, and holding the cache mutex across them would serialize every
|
|
175
|
+
// first-time resolution and risk deadlock if a custom meter re-entered record_value(). The
|
|
176
|
+
// meter returns a stable recorder for a given name/tag set, so resolving the same key twice on
|
|
177
|
+
// a race is harmless.
|
|
178
|
+
auto recorder = meter_->get_value_recorder(operation_meter_name, attrs.encode());
|
|
179
|
+
|
|
180
|
+
const std::scoped_lock lock(recorder_cache_mutex_);
|
|
181
|
+
// A concurrent caller may have inserted this key while the lock was released; emplace keeps the
|
|
182
|
+
// first-inserted recorder and returns it, so all callers share one recorder per key.
|
|
183
|
+
return recorder_cache_.emplace(attrs, std::move(recorder)).first->second;
|
|
158
184
|
}
|
|
159
185
|
|
|
160
186
|
void
|
|
161
187
|
meter_wrapper::record_value(metric_attributes attrs,
|
|
162
188
|
std::chrono::steady_clock::time_point start_time)
|
|
163
189
|
{
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
190
|
+
// The listener is optional -- the wrapper can be constructed without one -- so only enrich the
|
|
191
|
+
// attributes with cluster labels when it is present.
|
|
192
|
+
if (cluster_label_listener_) {
|
|
193
|
+
auto [cluster_name, cluster_uuid] = cluster_label_listener_->cluster_labels();
|
|
194
|
+
if (cluster_name) {
|
|
195
|
+
attrs.internal.cluster_name = cluster_name;
|
|
196
|
+
}
|
|
197
|
+
if (cluster_uuid) {
|
|
198
|
+
attrs.internal.cluster_uuid = cluster_uuid;
|
|
199
|
+
}
|
|
170
200
|
}
|
|
171
201
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
202
|
+
value_recorder_for(attrs)->record_value(std::chrono::duration_cast<std::chrono::microseconds>(
|
|
203
|
+
std::chrono::steady_clock::now() - start_time)
|
|
204
|
+
.count());
|
|
175
205
|
}
|
|
176
206
|
|
|
177
207
|
auto
|
|
@@ -25,9 +25,12 @@
|
|
|
25
25
|
|
|
26
26
|
#include <chrono>
|
|
27
27
|
#include <map>
|
|
28
|
+
#include <memory>
|
|
29
|
+
#include <mutex>
|
|
28
30
|
#include <optional>
|
|
29
31
|
#include <string>
|
|
30
32
|
#include <system_error>
|
|
33
|
+
#include <tuple>
|
|
31
34
|
|
|
32
35
|
#include "core/cluster_label_listener.hxx"
|
|
33
36
|
|
|
@@ -36,7 +39,11 @@ namespace couchbase::core::metrics
|
|
|
36
39
|
struct metric_attributes {
|
|
37
40
|
std::string service;
|
|
38
41
|
std::string operation;
|
|
39
|
-
|
|
42
|
+
// The standardized error type, precomputed once from the operation's error code (see
|
|
43
|
+
// standardized_error_type()). Stored rather than the raw error code so that both the encoded tag
|
|
44
|
+
// set and the recorder-cache key (operator<) use it without recomputing a string per comparison.
|
|
45
|
+
// Empty denotes "no error".
|
|
46
|
+
std::string error_type{};
|
|
40
47
|
std::optional<std::string> bucket_name{};
|
|
41
48
|
std::optional<std::string> scope_name{};
|
|
42
49
|
std::optional<std::string> collection_name{};
|
|
@@ -49,6 +56,38 @@ struct metric_attributes {
|
|
|
49
56
|
[[nodiscard]] auto encode() const -> std::map<std::string, std::string>;
|
|
50
57
|
};
|
|
51
58
|
|
|
59
|
+
// Map an error code to the standardized error-type string used as the metric's error_type tag (see
|
|
60
|
+
// metric_attributes::encode()). The empty string denotes "no error". Exposed so the recorder cache
|
|
61
|
+
// can key on the same bounded set of error types that actually reach the tags.
|
|
62
|
+
[[nodiscard]] auto
|
|
63
|
+
standardized_error_type(std::error_code ec) -> std::string;
|
|
64
|
+
|
|
65
|
+
inline auto
|
|
66
|
+
operator<(const metric_attributes& lhs, const metric_attributes& rhs) -> bool
|
|
67
|
+
{
|
|
68
|
+
// Order by the precomputed standardized error type, not the raw error code. encode() only ever
|
|
69
|
+
// emits the standardized type in the tag set, so keying on it collapses the many distinct codes
|
|
70
|
+
// that share a type onto one recorder and keeps the cache bounded by the tag cardinality (rather
|
|
71
|
+
// than one entry per raw code, unbounded for high-cardinality system/asio codes). Because the
|
|
72
|
+
// type is stored on the attributes, every comparison is a plain string compare -- no per-lookup
|
|
73
|
+
// string construction or allocation, which is what keeps the cache lookup cheap on the hot path.
|
|
74
|
+
return std::tie(lhs.service,
|
|
75
|
+
lhs.operation,
|
|
76
|
+
lhs.error_type,
|
|
77
|
+
lhs.bucket_name,
|
|
78
|
+
lhs.scope_name,
|
|
79
|
+
lhs.collection_name,
|
|
80
|
+
lhs.internal.cluster_name,
|
|
81
|
+
lhs.internal.cluster_uuid) < std::tie(rhs.service,
|
|
82
|
+
rhs.operation,
|
|
83
|
+
rhs.error_type,
|
|
84
|
+
rhs.bucket_name,
|
|
85
|
+
rhs.scope_name,
|
|
86
|
+
rhs.collection_name,
|
|
87
|
+
rhs.internal.cluster_name,
|
|
88
|
+
rhs.internal.cluster_uuid);
|
|
89
|
+
}
|
|
90
|
+
|
|
52
91
|
class meter_wrapper
|
|
53
92
|
{
|
|
54
93
|
public:
|
|
@@ -59,8 +98,12 @@ public:
|
|
|
59
98
|
void stop();
|
|
60
99
|
|
|
61
100
|
void record_value(metric_attributes attrs, std::chrono::steady_clock::time_point start_time);
|
|
62
|
-
|
|
63
|
-
|
|
101
|
+
|
|
102
|
+
// Resolve (and cache) the value recorder for a set of attributes. The underlying meter returns a
|
|
103
|
+
// stable recorder for a given name/tag set, so resolving once per distinct attribute set keeps
|
|
104
|
+
// the per-operation tag-map construction and recorder lookup off the hot path.
|
|
105
|
+
[[nodiscard]] auto value_recorder_for(const metric_attributes& attrs)
|
|
106
|
+
-> std::shared_ptr<couchbase::metrics::value_recorder>;
|
|
64
107
|
|
|
65
108
|
[[nodiscard]] auto wrapped() -> std::shared_ptr<couchbase::metrics::meter>;
|
|
66
109
|
|
|
@@ -71,5 +114,14 @@ public:
|
|
|
71
114
|
private:
|
|
72
115
|
std::shared_ptr<couchbase::metrics::meter> meter_;
|
|
73
116
|
std::shared_ptr<cluster_label_listener> cluster_label_listener_;
|
|
117
|
+
std::mutex recorder_cache_mutex_{};
|
|
118
|
+
// Keyed by the full attribute set (not just service/operation): the meter is pluggable, and a
|
|
119
|
+
// custom meter may hand out a distinct recorder per tag combination, so the cache must ask it
|
|
120
|
+
// once for each distinct attribute set rather than assume any particular dedup granularity. The
|
|
121
|
+
// key mirrors what encode() emits -- in particular it orders by the standardized error type (see
|
|
122
|
+
// operator<), not the raw error code -- so the key space is finite (services x operations x
|
|
123
|
+
// scope/collection x standardized error type x cluster) and the cache stays bounded.
|
|
124
|
+
std::map<metric_attributes, std::shared_ptr<couchbase::metrics::value_recorder>>
|
|
125
|
+
recorder_cache_{};
|
|
74
126
|
};
|
|
75
127
|
} // namespace couchbase::core::metrics
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2020-2021 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 "analytics_response_parsing.hxx"
|
|
19
|
+
|
|
20
|
+
#include "core/utils/duration_parser.hxx"
|
|
21
|
+
#include "core/utils/json.hxx"
|
|
22
|
+
|
|
23
|
+
#include <couchbase/error_codes.hxx>
|
|
24
|
+
|
|
25
|
+
#include <tao/json/value.hpp>
|
|
26
|
+
|
|
27
|
+
namespace couchbase::core::operations
|
|
28
|
+
{
|
|
29
|
+
|
|
30
|
+
auto
|
|
31
|
+
parse_analytics_meta(const tao::json::value& payload) -> analytics_response::analytics_meta_data
|
|
32
|
+
{
|
|
33
|
+
analytics_response::analytics_meta_data meta{};
|
|
34
|
+
|
|
35
|
+
if (const auto* i = payload.find("requestID"); i != nullptr) {
|
|
36
|
+
meta.request_id = i->get_string();
|
|
37
|
+
}
|
|
38
|
+
if (const auto* i = payload.find("clientContextID"); i != nullptr) {
|
|
39
|
+
meta.client_context_id = i->get_string();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (const auto* s = payload.find("status"); s != nullptr && s->is_string()) {
|
|
43
|
+
const auto& status = s->get_string();
|
|
44
|
+
if (status == "running") {
|
|
45
|
+
meta.status = analytics_response::analytics_status::running;
|
|
46
|
+
} else if (status == "success") {
|
|
47
|
+
meta.status = analytics_response::analytics_status::success;
|
|
48
|
+
} else if (status == "errors") {
|
|
49
|
+
meta.status = analytics_response::analytics_status::errors;
|
|
50
|
+
} else if (status == "completed") {
|
|
51
|
+
meta.status = analytics_response::analytics_status::completed;
|
|
52
|
+
} else if (status == "stopped") {
|
|
53
|
+
meta.status = analytics_response::analytics_status::stopped;
|
|
54
|
+
} else if (status == "timedout") {
|
|
55
|
+
meta.status = analytics_response::analytics_status::timedout;
|
|
56
|
+
} else if (status == "closed") {
|
|
57
|
+
meta.status = analytics_response::analytics_status::closed;
|
|
58
|
+
} else if (status == "fatal") {
|
|
59
|
+
meta.status = analytics_response::analytics_status::fatal;
|
|
60
|
+
} else if (status == "aborted") {
|
|
61
|
+
meta.status = analytics_response::analytics_status::aborted;
|
|
62
|
+
} else {
|
|
63
|
+
meta.status = analytics_response::analytics_status::unknown;
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
meta.status = analytics_response::analytics_status::unknown;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (const auto* s = payload.find("signature"); s != nullptr) {
|
|
70
|
+
meta.signature = couchbase::core::utils::json::generate(*s);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (const auto* m = payload.find("metrics"); m != nullptr) {
|
|
74
|
+
meta.metrics.result_count = m->at("resultCount").get_unsigned();
|
|
75
|
+
meta.metrics.result_size = m->at("resultSize").get_unsigned();
|
|
76
|
+
meta.metrics.elapsed_time = utils::parse_duration(m->at("elapsedTime").get_string());
|
|
77
|
+
meta.metrics.execution_time = utils::parse_duration(m->at("executionTime").get_string());
|
|
78
|
+
meta.metrics.processed_objects = m->at("processedObjects").get_unsigned();
|
|
79
|
+
meta.metrics.error_count = m->optional<std::uint64_t>("errorCount").value_or(0);
|
|
80
|
+
meta.metrics.warning_count = m->optional<std::uint64_t>("warningCount").value_or(0);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (const auto* e = payload.find("errors"); e != nullptr) {
|
|
84
|
+
for (const auto& err : e->get_array()) {
|
|
85
|
+
analytics_response::analytics_problem problem;
|
|
86
|
+
problem.code = err.at("code").get_unsigned();
|
|
87
|
+
problem.message = err.at("msg").get_string();
|
|
88
|
+
meta.errors.emplace_back(problem);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (const auto* w = payload.find("warnings"); w != nullptr) {
|
|
93
|
+
for (const auto& warn : w->get_array()) {
|
|
94
|
+
analytics_response::analytics_problem problem;
|
|
95
|
+
problem.code = warn.at("code").get_unsigned();
|
|
96
|
+
problem.message = warn.at("msg").get_string();
|
|
97
|
+
meta.warnings.emplace_back(problem);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return meta;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
auto
|
|
105
|
+
map_analytics_error(const analytics_response::analytics_meta_data& meta, std::uint32_t http_status)
|
|
106
|
+
-> std::error_code
|
|
107
|
+
{
|
|
108
|
+
if (meta.status == analytics_response::analytics_status::success && http_status != 400) {
|
|
109
|
+
return {};
|
|
110
|
+
}
|
|
111
|
+
const auto unmatched =
|
|
112
|
+
http_status == 400 ? errc::common::invalid_argument : errc::common::internal_server_failure;
|
|
113
|
+
|
|
114
|
+
if (meta.errors.empty()) {
|
|
115
|
+
/* Reachable from make_response, which calls this for any non-success status even when the
|
|
116
|
+
* payload carries no "errors" array, and from the streaming-path caller, which has no such
|
|
117
|
+
* guarantee either. */
|
|
118
|
+
return unmatched;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const auto first_error_code = meta.errors.front().code;
|
|
122
|
+
|
|
123
|
+
std::error_code ec{};
|
|
124
|
+
switch (first_error_code) {
|
|
125
|
+
case 21002: /* Request timed out and will be cancelled */
|
|
126
|
+
ec = errc::common::unambiguous_timeout;
|
|
127
|
+
break;
|
|
128
|
+
case 24000: /* RFC-58: ParsingFailure */
|
|
129
|
+
ec = errc::common::parsing_failure;
|
|
130
|
+
break;
|
|
131
|
+
case 23000: /* RFC-58: TemporaryFailure */
|
|
132
|
+
case 23003: /* RFC-58: TemporaryFailure */
|
|
133
|
+
ec = errc::common::temporary_failure;
|
|
134
|
+
break;
|
|
135
|
+
case 23007: /* Job queue is full with [string] jobs */
|
|
136
|
+
ec = errc::analytics::job_queue_full;
|
|
137
|
+
break;
|
|
138
|
+
case 24044: /* Cannot find dataset [string] because there is no dataverse declared, nor an
|
|
139
|
+
alias with name [string]! */
|
|
140
|
+
case 24045: /* Cannot find dataset [string] in dataverse [string] nor an alias with name
|
|
141
|
+
[string]! */
|
|
142
|
+
case 24025: /* Cannot find dataset with name [string] in dataverse [string] */
|
|
143
|
+
ec = errc::analytics::dataset_not_found;
|
|
144
|
+
break;
|
|
145
|
+
case 24034: /* Cannot find dataverse with name [string] */
|
|
146
|
+
ec = errc::analytics::dataverse_not_found;
|
|
147
|
+
break;
|
|
148
|
+
case 24040: /* A dataset with name [string] already exists in dataverse [string] */
|
|
149
|
+
ec = errc::analytics::dataset_exists;
|
|
150
|
+
break;
|
|
151
|
+
case 24039: /* A dataverse with this name [string] already exists. */
|
|
152
|
+
ec = errc::analytics::dataverse_exists;
|
|
153
|
+
break;
|
|
154
|
+
case 24006: /* Link [string] does not exist | Link [string] does not exist */
|
|
155
|
+
ec = errc::analytics::link_not_found;
|
|
156
|
+
break;
|
|
157
|
+
default:
|
|
158
|
+
// RFC-58 maps these ranges whatever the HTTP status, so a 400 carrying one is not
|
|
159
|
+
// invalid_argument.
|
|
160
|
+
if (first_error_code >= 24000 && first_error_code < 25000) {
|
|
161
|
+
ec = errc::analytics::compilation_failure;
|
|
162
|
+
} else if (first_error_code >= 20000 && first_error_code < 21000) {
|
|
163
|
+
ec = errc::common::authentication_failure;
|
|
164
|
+
} else if (first_error_code >= 25000 && first_error_code < 26000) {
|
|
165
|
+
ec = errc::common::internal_server_failure;
|
|
166
|
+
}
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (!ec) {
|
|
171
|
+
ec = unmatched;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return ec;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
} // namespace couchbase::core::operations
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2020-2021 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
|
+
#pragma once
|
|
19
|
+
|
|
20
|
+
#include "core/operations/document_analytics.hxx"
|
|
21
|
+
|
|
22
|
+
#include <couchbase/error_codes.hxx>
|
|
23
|
+
|
|
24
|
+
#include <tao/json/forward.hpp>
|
|
25
|
+
|
|
26
|
+
#include <cstdint>
|
|
27
|
+
#include <system_error>
|
|
28
|
+
|
|
29
|
+
namespace couchbase::core::operations
|
|
30
|
+
{
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Parse analytics meta-data fields (status, metrics, warnings, errors, signature, requestID,
|
|
34
|
+
* clientContextID) from a top-level response payload.
|
|
35
|
+
*
|
|
36
|
+
* Pure function — no side effects, no access to request state.
|
|
37
|
+
*/
|
|
38
|
+
auto
|
|
39
|
+
parse_analytics_meta(const tao::json::value& payload) -> analytics_response::analytics_meta_data;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Map analytics meta-data to an error_code.
|
|
43
|
+
*
|
|
44
|
+
* Pure classifier — no side effects, no exceptions thrown. Returns an empty error_code when the
|
|
45
|
+
* analytics query succeeded (meta.status == success and http_status is not 400).
|
|
46
|
+
*
|
|
47
|
+
* http_status is the status of the response that carried the metadata, or 0 where there is none.
|
|
48
|
+
* A failure that matches no specific mapping is invalid_argument for an HTTP 400 (RFC-58) and
|
|
49
|
+
* internal_server_failure otherwise.
|
|
50
|
+
*/
|
|
51
|
+
[[nodiscard]] auto
|
|
52
|
+
map_analytics_error(const analytics_response::analytics_meta_data& meta,
|
|
53
|
+
std::uint32_t http_status = 0) -> std::error_code;
|
|
54
|
+
|
|
55
|
+
} // namespace couchbase::core::operations
|