couchbase 3.8.1 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/ext/CMakeLists.txt +16 -1
- data/ext/cache/cpm/{CPM_0.42.0.cmake → CPM_0.43.1.cmake} +18 -2
- data/ext/cache/extconf_include.rb +6 -6
- data/ext/cache/mozilla-ca-bundle.crt +214 -155
- data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
- data/ext/couchbase/CMakeLists.txt +130 -21
- data/ext/couchbase/cmake/APKBUILD.in +25 -4
- data/ext/couchbase/cmake/Bundler.cmake +143 -34
- data/ext/couchbase/cmake/CPM.cmake +126 -12
- data/ext/couchbase/cmake/Cache.cmake +7 -1
- data/ext/couchbase/cmake/CompilerOptions.cmake +1 -1
- data/ext/couchbase/cmake/CompilerWarnings.cmake +17 -6
- data/ext/couchbase/cmake/GrpcProtobuf.cmake +481 -0
- data/ext/couchbase/cmake/OpenSSL.cmake +10 -3
- data/ext/couchbase/cmake/Packaging.cmake +519 -65
- data/ext/couchbase/cmake/Protostellar.cmake +250 -0
- data/ext/couchbase/cmake/Sanitizers.cmake +61 -50
- data/ext/couchbase/cmake/StaticAnalyzers.cmake +16 -5
- data/ext/couchbase/cmake/TestFramework.cmake +283 -0
- data/ext/couchbase/cmake/TestFrameworkAddTests.cmake +51 -0
- data/ext/couchbase/cmake/Testing.cmake +27 -9
- data/ext/couchbase/cmake/ThirdPartyDependencies.cmake +141 -8
- data/ext/couchbase/cmake/VersionInfo.cmake +50 -0
- data/ext/couchbase/cmake/build_config.hxx.in +2 -1
- data/ext/couchbase/cmake/couchbase-cxx-client.spec.in +101 -23
- data/ext/couchbase/cmake/couchbase_cxx_client_static-config.cmake.in +7 -0
- data/ext/couchbase/cmake/couchbase_cxx_client_static.pc.in +2 -0
- data/ext/couchbase/cmake/gRPC_Generate.cmake +58 -0
- data/ext/couchbase/cmake/protobuf_Generate.cmake +69 -0
- data/ext/couchbase/cmake/require-git-checkout.cmake +25 -0
- data/ext/couchbase/cmake/tarball_glob.txt +49 -0
- data/ext/couchbase/core/agent_group.cxx +0 -8
- data/ext/couchbase/core/agent_group.hxx +0 -4
- data/ext/couchbase/core/analytics_stream.cxx +314 -0
- data/ext/couchbase/core/analytics_stream.hxx +129 -0
- data/ext/couchbase/core/analytics_stream_component.cxx +245 -0
- data/ext/couchbase/core/analytics_stream_component.hxx +67 -0
- data/ext/couchbase/core/app_telemetry_meter.cxx +25 -3
- data/ext/couchbase/core/app_telemetry_meter.hxx +77 -0
- data/ext/couchbase/core/app_telemetry_reporter.cxx +7 -6
- data/ext/couchbase/core/bucket.cxx +381 -87
- data/ext/couchbase/core/bucket.hxx +105 -25
- data/ext/couchbase/core/bucket_unit_test_api.hxx +57 -0
- data/ext/couchbase/core/capella.hxx +91 -0
- data/ext/couchbase/core/cluster.cxx +1554 -398
- data/ext/couchbase/core/cluster.hxx +39 -8
- data/ext/couchbase/core/cluster_agent.cxx +0 -8
- data/ext/couchbase/core/cluster_agent.hxx +0 -4
- data/ext/couchbase/core/cluster_options.hxx +26 -3
- data/ext/couchbase/core/collections_component.cxx +39 -15
- data/ext/couchbase/core/config_profiles.cxx +1 -1
- data/ext/couchbase/core/crud_component.cxx +2 -2
- data/ext/couchbase/core/crud_options.hxx +34 -0
- data/ext/couchbase/core/crypto/cbcrypto.cc +18 -13
- data/ext/couchbase/core/document_id_redaction.hxx +81 -0
- data/ext/couchbase/core/error_context/base_error_context.hxx +7 -6
- data/ext/couchbase/core/error_context/key_value.cxx +25 -2
- data/ext/couchbase/core/error_context/key_value.hxx +60 -33
- data/ext/couchbase/core/error_context/key_value_error_context.hxx +16 -15
- data/ext/couchbase/core/error_context/search.hxx +5 -0
- data/ext/couchbase/core/error_context/search_json.hxx +3 -0
- data/ext/couchbase/core/error_context/subdocument_error_context.hxx +19 -18
- data/ext/couchbase/core/error_context/view.hxx +5 -0
- data/ext/couchbase/core/free_form_http_request.cxx +237 -4
- data/ext/couchbase/core/free_form_http_request.hxx +41 -8
- data/ext/couchbase/core/http_component.cxx +300 -284
- data/ext/couchbase/core/http_component.hxx +0 -4
- data/ext/couchbase/core/impl/analytics.cxx +38 -5
- data/ext/couchbase/core/impl/analytics.hxx +34 -0
- data/ext/couchbase/core/impl/bootstrap_error.hxx +0 -3
- data/ext/couchbase/core/impl/collection.cxx +215 -202
- data/ext/couchbase/core/impl/collection_manager.cxx +1 -1
- data/ext/couchbase/core/impl/dns_srv_tracker.cxx +45 -18
- data/ext/couchbase/core/impl/error.cxx +22 -2
- data/ext/couchbase/core/impl/internal_analytics_stream_result.hxx +111 -0
- data/ext/couchbase/core/impl/internal_query_stream_result.hxx +110 -0
- data/ext/couchbase/core/impl/invoke_with_node_id.hxx +15 -7
- data/ext/couchbase/core/impl/key_value_error_category.cxx +6 -0
- data/ext/couchbase/core/impl/lookup_in_replica.cxx +10 -10
- data/ext/couchbase/core/impl/lookup_in_replica.hxx +4 -4
- data/ext/couchbase/core/impl/node_id.cxx +49 -13
- data/ext/couchbase/core/impl/observability_recorder.cxx +12 -2
- data/ext/couchbase/core/impl/observe_poll.cxx +63 -23
- data/ext/couchbase/core/impl/public_analytics_stream_result.cxx +372 -0
- data/ext/couchbase/core/impl/public_bucket.cxx +48 -2
- data/ext/couchbase/core/impl/public_cluster.cxx +325 -25
- data/ext/couchbase/core/impl/public_query_stream_result.cxx +380 -0
- data/ext/couchbase/core/impl/public_transaction_get_multi_replicas_from_preferred_server_group_result.cxx +42 -0
- data/ext/couchbase/core/impl/public_transaction_get_multi_result.cxx +42 -0
- data/ext/couchbase/core/impl/query.cxx +76 -7
- data/ext/couchbase/core/impl/query.hxx +36 -0
- data/ext/couchbase/core/impl/query_index_manager.cxx +54 -1
- data/ext/couchbase/core/impl/replica_utils.cxx +101 -0
- data/ext/couchbase/core/impl/replica_utils.hxx +64 -0
- data/ext/couchbase/core/impl/resolve_node_id.hxx +125 -0
- data/ext/couchbase/core/impl/scope.cxx +70 -0
- data/ext/couchbase/core/impl/search.cxx +31 -1
- data/ext/couchbase/core/impl/transactions.cxx +130 -0
- data/ext/couchbase/core/impl/wait_until_ready.cxx +439 -0
- data/ext/couchbase/core/impl/wait_until_ready.hxx +110 -0
- data/ext/couchbase/core/impl/with_bucket_config_or_timeout.hxx +180 -0
- data/ext/couchbase/core/impl/with_cancellation.hxx +11 -3
- data/ext/couchbase/core/io/configuration_belongs_to_session.hxx +66 -0
- data/ext/couchbase/core/io/dns_client.cxx +122 -45
- data/ext/couchbase/core/io/dns_codec.hxx +21 -21
- data/ext/couchbase/core/io/dns_config.cxx +21 -6
- data/ext/couchbase/core/io/http_command.hxx +149 -121
- data/ext/couchbase/core/io/http_error.hxx +107 -0
- data/ext/couchbase/core/io/http_parser.cxx +4 -0
- data/ext/couchbase/core/io/http_session.cxx +606 -154
- data/ext/couchbase/core/io/http_session.hxx +147 -30
- data/ext/couchbase/core/io/http_session_manager.hxx +329 -382
- data/ext/couchbase/core/io/http_streaming_parser.cxx +4 -0
- data/ext/couchbase/core/io/http_streaming_response.cxx +328 -43
- data/ext/couchbase/core/io/http_streaming_response.hxx +37 -3
- data/ext/couchbase/core/io/mcbp_buffer_pool.hxx +122 -0
- data/ext/couchbase/core/io/mcbp_command.hxx +150 -51
- data/ext/couchbase/core/io/mcbp_command_id.hxx +45 -0
- data/ext/couchbase/core/io/mcbp_message.cxx +9 -1
- data/ext/couchbase/core/io/mcbp_message.hxx +19 -0
- data/ext/couchbase/core/io/mcbp_output_queue.hxx +150 -0
- data/ext/couchbase/core/io/mcbp_parser.cxx +24 -7
- data/ext/couchbase/core/io/mcbp_session.cxx +316 -317
- data/ext/couchbase/core/io/mcbp_session.hxx +27 -18
- data/ext/couchbase/core/io/opaque_ring_table.hxx +145 -0
- data/ext/couchbase/core/io/retry_orchestrator.hxx +6 -5
- data/ext/couchbase/core/io/stream_deadline.hxx +50 -0
- data/ext/couchbase/core/io/streams.cxx +275 -14
- data/ext/couchbase/core/io/streams.hxx +53 -0
- data/ext/couchbase/core/logger/logger.cxx +36 -0
- data/ext/couchbase/core/logger/logger.hxx +46 -6
- data/ext/couchbase/core/logger/redaction.hxx +503 -0
- data/ext/couchbase/core/management/eventing_status.hxx +10 -0
- data/ext/couchbase/core/management/eventing_status_json.hxx +4 -0
- data/ext/couchbase/core/mcbp/big_endian.cxx +1 -1
- data/ext/couchbase/core/mcbp/codec.cxx +27 -18
- data/ext/couchbase/core/mcbp/operation_queue.cxx +2 -2
- data/ext/couchbase/core/mcbp/packet.hxx +2 -2
- data/ext/couchbase/core/mcbp/queue_request.cxx +23 -6
- data/ext/couchbase/core/mcbp/queue_request.hxx +21 -0
- data/ext/couchbase/core/meta/features.hxx +13 -0
- data/ext/couchbase/core/meta/version.cxx +6 -3
- data/ext/couchbase/core/metrics/logging_meter.cxx +5 -10
- data/ext/couchbase/core/metrics/meter_wrapper.cxx +63 -33
- data/ext/couchbase/core/metrics/meter_wrapper.hxx +55 -3
- data/ext/couchbase/core/operations/analytics_response_parsing.cxx +177 -0
- data/ext/couchbase/core/operations/analytics_response_parsing.hxx +55 -0
- data/ext/couchbase/core/operations/document_analytics.cxx +48 -130
- data/ext/couchbase/core/operations/document_analytics.hxx +14 -2
- data/ext/couchbase/core/operations/document_get_all_replicas.hxx +15 -7
- data/ext/couchbase/core/operations/document_get_any_replica.hxx +19 -8
- data/ext/couchbase/core/operations/document_get_projected.cxx +1 -1
- data/ext/couchbase/core/{impl/get_replica.cxx → operations/document_get_replica.cxx} +21 -3
- data/ext/couchbase/core/{impl/get_replica.hxx → operations/document_get_replica.hxx} +31 -4
- data/ext/couchbase/core/operations/document_lookup_in.cxx +10 -10
- data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +228 -198
- data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +215 -217
- data/ext/couchbase/core/operations/document_query.cxx +108 -221
- data/ext/couchbase/core/operations/document_query.hxx +18 -4
- data/ext/couchbase/core/operations/document_search.cxx +52 -8
- data/ext/couchbase/core/operations/document_search.hxx +3 -0
- data/ext/couchbase/core/operations/document_view.cxx +3 -3
- data/ext/couchbase/core/operations/management/analytics_dataset_create.cxx +15 -8
- data/ext/couchbase/core/operations/management/analytics_dataset_create.hxx +4 -0
- data/ext/couchbase/core/operations/management/analytics_dataset_drop.cxx +11 -6
- data/ext/couchbase/core/operations/management/analytics_dataset_get_all.cxx +3 -2
- data/ext/couchbase/core/operations/management/analytics_dataverse_create.cxx +10 -5
- data/ext/couchbase/core/operations/management/analytics_dataverse_drop.cxx +10 -5
- data/ext/couchbase/core/operations/management/analytics_get_pending_mutations.cxx +2 -1
- data/ext/couchbase/core/operations/management/analytics_index_create.cxx +33 -8
- data/ext/couchbase/core/operations/management/analytics_index_drop.cxx +12 -7
- data/ext/couchbase/core/operations/management/analytics_index_get_all.cxx +3 -2
- data/ext/couchbase/core/operations/management/analytics_link_connect.cxx +11 -6
- data/ext/couchbase/core/operations/management/analytics_link_create.cxx +3 -3
- data/ext/couchbase/core/operations/management/analytics_link_disconnect.cxx +10 -4
- data/ext/couchbase/core/operations/management/analytics_link_drop.cxx +6 -4
- data/ext/couchbase/core/operations/management/analytics_link_get_all.cxx +4 -3
- data/ext/couchbase/core/operations/management/analytics_link_replace.cxx +3 -3
- data/ext/couchbase/core/operations/management/analytics_link_utils.hxx +1 -1
- data/ext/couchbase/core/operations/management/bucket_create.cxx +37 -38
- data/ext/couchbase/core/operations/management/bucket_update.cxx +26 -28
- data/ext/couchbase/core/operations/management/change_password.cxx +2 -0
- data/ext/couchbase/core/operations/management/collection_drop.cxx +5 -1
- data/ext/couchbase/core/operations/management/error_utils.cxx +59 -5
- data/ext/couchbase/core/operations/management/error_utils.hxx +29 -1
- data/ext/couchbase/core/operations/management/eventing_deploy_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/eventing_drop_function.cxx +8 -3
- data/ext/couchbase/core/operations/management/eventing_get_all_functions.cxx +4 -2
- data/ext/couchbase/core/operations/management/eventing_get_function.cxx +5 -3
- data/ext/couchbase/core/operations/management/eventing_get_status.cxx +4 -2
- data/ext/couchbase/core/operations/management/eventing_pause_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/eventing_resume_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/eventing_undeploy_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/eventing_upsert_function.cxx +9 -3
- data/ext/couchbase/core/operations/management/group_drop.cxx +3 -1
- data/ext/couchbase/core/operations/management/group_get.cxx +3 -1
- data/ext/couchbase/core/operations/management/group_upsert.cxx +11 -8
- data/ext/couchbase/core/operations/management/query_index_build.cxx +5 -2
- data/ext/couchbase/core/operations/management/query_index_create.cxx +9 -3
- data/ext/couchbase/core/operations/management/query_index_drop.cxx +11 -4
- data/ext/couchbase/core/operations/management/query_index_get_all.cxx +1 -1
- data/ext/couchbase/core/operations/management/query_index_get_all_deferred.cxx +1 -1
- data/ext/couchbase/core/operations/management/scope_drop.cxx +5 -1
- data/ext/couchbase/core/operations/management/scope_get_all.cxx +6 -1
- data/ext/couchbase/core/operations/management/search_get_stats.cxx +10 -0
- data/ext/couchbase/core/operations/management/search_index_analyze_document.cxx +3 -2
- data/ext/couchbase/core/operations/management/search_index_control_ingest.cxx +4 -3
- data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.cxx +4 -3
- data/ext/couchbase/core/operations/management/search_index_control_query.cxx +4 -3
- data/ext/couchbase/core/operations/management/search_index_drop.cxx +2 -2
- data/ext/couchbase/core/operations/management/search_index_get.cxx +2 -2
- data/ext/couchbase/core/operations/management/search_index_get_documents_count.cxx +3 -2
- data/ext/couchbase/core/operations/management/search_index_get_stats.cxx +3 -1
- data/ext/couchbase/core/operations/management/search_index_upsert.cxx +2 -2
- data/ext/couchbase/core/operations/management/user_drop.cxx +3 -1
- data/ext/couchbase/core/operations/management/user_get.cxx +3 -1
- data/ext/couchbase/core/operations/management/user_upsert.cxx +12 -9
- data/ext/couchbase/core/operations/management/view_index_drop.cxx +1 -1
- data/ext/couchbase/core/operations/management/view_index_get.cxx +1 -1
- data/ext/couchbase/core/operations/management/view_index_upsert.cxx +1 -1
- data/ext/couchbase/core/operations/operation_traits.hxx +18 -0
- data/ext/couchbase/core/operations/query_response_parsing.cxx +211 -0
- data/ext/couchbase/core/operations/query_response_parsing.hxx +60 -0
- data/ext/couchbase/core/operations_fwd.hxx +3 -3
- data/ext/couchbase/core/origin.cxx +54 -26
- data/ext/couchbase/core/origin.hxx +12 -0
- data/ext/couchbase/core/orphan_reporter.cxx +2 -1
- data/ext/couchbase/core/platform/random.cc +7 -7
- data/ext/couchbase/core/protocol/client_request.cxx +2 -2
- data/ext/couchbase/core/protocol/client_request.hxx +38 -21
- data/ext/couchbase/core/protocol/client_response.cxx +11 -3
- data/ext/couchbase/core/protocol/client_response.hxx +27 -6
- data/ext/couchbase/core/protocol/cmd_append.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_cluster_map_change_notification.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_decrement.cxx +6 -6
- data/ext/couchbase/core/protocol/cmd_get.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_get_and_lock.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_get_and_touch.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_get_cluster_config.cxx +6 -4
- data/ext/couchbase/core/protocol/cmd_get_collection_id.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_get_error_map.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_get_meta.cxx +4 -4
- data/ext/couchbase/core/protocol/cmd_get_replica.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_hello.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_increment.cxx +6 -6
- data/ext/couchbase/core/protocol/cmd_insert.cxx +4 -4
- data/ext/couchbase/core/protocol/cmd_lookup_in.cxx +4 -3
- data/ext/couchbase/core/protocol/cmd_lookup_in_replica.cxx +4 -3
- data/ext/couchbase/core/protocol/cmd_mutate_in.cxx +10 -9
- data/ext/couchbase/core/protocol/cmd_mutate_in.hxx +10 -10
- data/ext/couchbase/core/protocol/cmd_observe_seqno.cxx +7 -7
- data/ext/couchbase/core/protocol/cmd_prepend.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_remove.cxx +2 -2
- data/ext/couchbase/core/protocol/cmd_replace.cxx +4 -4
- data/ext/couchbase/core/protocol/cmd_touch.cxx +1 -1
- data/ext/couchbase/core/protocol/cmd_upsert.cxx +4 -4
- data/ext/couchbase/core/protocol/datatype.hxx +118 -1
- data/ext/couchbase/core/protocol/frame_info_utils.cxx +1 -1
- data/ext/couchbase/core/protocol/magic.hxx +4 -0
- data/ext/couchbase/core/protocol/magic_fmt.hxx +3 -0
- data/ext/couchbase/core/protocol/server_request.hxx +3 -1
- data/ext/couchbase/core/protocol/status.cxx +1 -1
- data/ext/couchbase/core/protostellar/analytics_converter.hxx +171 -0
- data/ext/couchbase/core/protostellar/bucket_admin_converter.hxx +301 -0
- data/ext/couchbase/core/protostellar/collection_admin_converter.hxx +92 -0
- data/ext/couchbase/core/protostellar/component.cxx +2445 -0
- data/ext/couchbase/core/protostellar/component.hxx +391 -0
- data/ext/couchbase/core/{columnar/bootstrap_notification_subscriber.hxx → protostellar/compression_settings.hxx} +11 -10
- data/ext/couchbase/core/protostellar/credentials.cxx +233 -0
- data/ext/couchbase/core/protostellar/credentials.hxx +88 -0
- data/ext/couchbase/core/protostellar/dispatcher.cxx +57 -0
- data/ext/couchbase/core/protostellar/dispatcher.hxx +482 -0
- data/ext/couchbase/core/protostellar/error_utils.cxx +293 -0
- data/ext/couchbase/core/protostellar/error_utils.hxx +97 -0
- data/ext/couchbase/core/protostellar/json_payload.hxx +49 -0
- data/ext/couchbase/core/protostellar/kv_converter.cxx +70 -0
- data/ext/couchbase/core/protostellar/kv_converter.hxx +600 -0
- data/ext/couchbase/core/protostellar/query_converter.hxx +265 -0
- data/ext/couchbase/core/protostellar/query_index_admin_converter.hxx +291 -0
- data/ext/couchbase/core/protostellar/query_proto.hxx +73 -0
- data/ext/couchbase/core/protostellar/search_converter.hxx +244 -0
- data/ext/couchbase/core/protostellar/search_index_admin_converter.hxx +156 -0
- data/ext/couchbase/core/protostellar/view_converter.hxx +158 -0
- data/ext/couchbase/core/query_stream.cxx +447 -0
- data/ext/couchbase/core/query_stream.hxx +141 -0
- data/ext/couchbase/core/query_stream_component.cxx +243 -0
- data/ext/couchbase/core/query_stream_component.hxx +68 -0
- data/ext/couchbase/core/range_scan_load_balancer.cxx +15 -8
- data/ext/couchbase/core/range_scan_orchestrator.cxx +15 -3
- data/ext/couchbase/core/response_handler.hxx +41 -4
- data/ext/couchbase/core/row_streamer.cxx +332 -46
- data/ext/couchbase/core/row_streamer.hxx +31 -1
- data/ext/couchbase/core/row_streamer_options.hxx +55 -0
- data/ext/couchbase/core/sasl/client.h +3 -0
- data/ext/couchbase/core/search_scoring.hxx +66 -0
- data/ext/couchbase/core/stream_error_details.hxx +69 -0
- data/ext/couchbase/core/timeout_defaults.hxx +0 -1
- data/ext/couchbase/core/topology/capabilities.hxx +6 -0
- data/ext/couchbase/core/topology/capabilities_fmt.hxx +3 -0
- data/ext/couchbase/core/topology/configuration.cxx +21 -6
- data/ext/couchbase/core/topology/configuration.hxx +29 -8
- data/ext/couchbase/core/topology/configuration_json.hxx +3 -0
- data/ext/couchbase/core/topology/error_map_json.hxx +3 -1
- data/ext/couchbase/core/tracing/threshold_logging_tracer.cxx +70 -4
- data/ext/couchbase/core/tracing/threshold_logging_tracer.hxx +10 -0
- data/ext/couchbase/core/transactions/active_transaction_record.cxx +0 -34
- data/ext/couchbase/core/transactions/attempt_context_impl.cxx +362 -241
- data/ext/couchbase/core/transactions/attempt_context_impl.hxx +24 -3
- data/ext/couchbase/core/transactions/error_list.hxx +2 -2
- data/ext/couchbase/core/transactions/get_multi_fetch.hxx +160 -0
- data/ext/couchbase/core/transactions/get_multi_orchestrator.cxx +326 -125
- data/ext/couchbase/core/transactions/get_multi_transaction_id.hxx +62 -0
- data/ext/couchbase/core/transactions/internal/atr_entry.hxx +22 -2
- data/ext/couchbase/core/transactions/internal/transaction_context.hxx +2 -2
- data/ext/couchbase/core/transactions/internal/transactions_cleanup.hxx +23 -1
- data/ext/couchbase/core/transactions/internal/utils.hxx +50 -14
- data/ext/couchbase/core/transactions/staged_mutation.cxx +23 -18
- data/ext/couchbase/core/transactions/staged_mutation.hxx +15 -4
- data/ext/couchbase/core/transactions/transaction_context.cxx +55 -40
- data/ext/couchbase/core/transactions/transaction_get_result.hxx +16 -0
- data/ext/couchbase/core/transactions/transactions.cxx +3 -55
- data/ext/couchbase/core/transactions/transactions_cleanup.cxx +194 -66
- data/ext/couchbase/core/transactions/transactions_config.cxx +0 -11
- data/ext/couchbase/core/transactions/utils.cxx +10 -0
- data/ext/couchbase/core/transactions/waitable_op_list.hxx +15 -4
- data/ext/couchbase/core/transactions.hxx +9 -9
- data/ext/couchbase/core/utils/byteswap.hxx +166 -9
- data/ext/couchbase/core/utils/connection_string.cxx +50 -85
- data/ext/couchbase/core/utils/connection_string.hxx +15 -0
- data/ext/couchbase/core/{columnar/backoff_calculator.hxx → utils/deadline.hxx} +13 -13
- data/ext/couchbase/core/utils/duration_parser.cxx +1 -1
- data/ext/couchbase/core/utils/json_streaming_lexer.cxx +48 -5
- data/ext/couchbase/core/utils/json_streaming_lexer.hxx +4 -1
- data/ext/couchbase/core/utils/movable_function.hxx +301 -52
- data/ext/couchbase/core/utils/name_codec.hxx +154 -11
- data/ext/couchbase/core/{columnar/retry_info.hxx → utils/process_id.hxx} +18 -13
- data/ext/couchbase/core/utils/url_codec.cxx +12 -51
- data/ext/couchbase/core/websocket_codec.cxx +3 -29
- data/ext/couchbase/couchbase/analytics_options.hxx +21 -10
- data/ext/couchbase/couchbase/analytics_row.hxx +105 -0
- data/ext/couchbase/couchbase/analytics_stream_result.hxx +266 -0
- data/ext/couchbase/couchbase/boolean_query.hxx +3 -3
- data/ext/couchbase/couchbase/bucket.hxx +57 -0
- data/ext/couchbase/couchbase/cluster.hxx +216 -5
- data/ext/couchbase/{core/columnar/security_options.hxx → couchbase/cluster_state.hxx} +18 -14
- data/ext/couchbase/couchbase/codec/lenient_json_transcoder.hxx +69 -0
- data/ext/couchbase/couchbase/collection.hxx +234 -14
- data/ext/couchbase/couchbase/common_durability_options.hxx +18 -3
- data/ext/couchbase/couchbase/conjunction_query.hxx +1 -1
- data/ext/couchbase/couchbase/create_dataset_analytics_options.hxx +6 -1
- data/ext/couchbase/couchbase/date_range_query.hxx +2 -2
- data/ext/couchbase/couchbase/decrement_options.hxx +1 -1
- data/ext/couchbase/couchbase/disjunction_query.hxx +1 -1
- data/ext/couchbase/couchbase/error.hxx +32 -0
- data/ext/couchbase/couchbase/error_codes.hxx +32 -0
- data/ext/couchbase/couchbase/geo_bounding_box_query.hxx +1 -1
- data/ext/couchbase/couchbase/geo_distance_query.hxx +1 -1
- data/ext/couchbase/couchbase/geo_polygon_query.hxx +1 -1
- data/ext/couchbase/couchbase/get_replica_options.hxx +68 -0
- data/ext/couchbase/couchbase/get_replica_result.hxx +5 -3
- data/ext/couchbase/couchbase/get_replica_strategy.hxx +161 -0
- data/ext/couchbase/couchbase/get_result.hxx +1 -0
- data/ext/couchbase/couchbase/increment_options.hxx +1 -1
- data/ext/couchbase/couchbase/insert_options.hxx +1 -1
- data/ext/couchbase/couchbase/match_phrase_query.hxx +1 -1
- data/ext/couchbase/couchbase/match_query.hxx +1 -1
- data/ext/couchbase/couchbase/mutate_in_options.hxx +3 -3
- data/ext/couchbase/couchbase/network_options.hxx +1 -1
- data/ext/couchbase/couchbase/node_id.hxx +42 -14
- data/ext/couchbase/couchbase/node_id_for_options.hxx +7 -1
- data/ext/couchbase/couchbase/node_ids_options.hxx +8 -2
- data/ext/couchbase/couchbase/numeric_range_query.hxx +1 -1
- data/ext/couchbase/couchbase/phrase_query.hxx +1 -1
- data/ext/couchbase/couchbase/prefix_query.hxx +1 -1
- data/ext/couchbase/couchbase/query_options.hxx +23 -12
- data/ext/couchbase/couchbase/query_row.hxx +111 -0
- data/ext/couchbase/couchbase/query_stream_result.hxx +302 -0
- data/ext/couchbase/couchbase/query_string_query.hxx +3 -3
- data/ext/couchbase/couchbase/regexp_query.hxx +1 -1
- data/ext/couchbase/couchbase/replace_options.hxx +3 -3
- data/ext/couchbase/couchbase/result.hxx +14 -3
- data/ext/couchbase/couchbase/scan_result_item.hxx +1 -0
- data/ext/couchbase/couchbase/scope.hxx +85 -2
- data/ext/couchbase/couchbase/search_options.hxx +58 -8
- data/ext/couchbase/couchbase/search_scoring.hxx +94 -0
- data/ext/couchbase/couchbase/search_scoring_none.hxx +51 -0
- data/ext/couchbase/couchbase/search_scoring_reciprocal_rank_fusion.hxx +88 -0
- data/ext/couchbase/couchbase/search_scoring_relative_score_fusion.hxx +70 -0
- data/ext/couchbase/couchbase/term_range_query.hxx +1 -1
- data/ext/couchbase/couchbase/tracing/request_span.hxx +46 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_result.hxx +23 -21
- data/ext/couchbase/couchbase/transactions/transaction_get_multi_result.hxx +24 -19
- data/ext/couchbase/couchbase/transactions/transaction_get_result.hxx +17 -3
- data/ext/couchbase/couchbase/transactions/transactions_config.hxx +4 -2
- data/ext/couchbase/couchbase/transactions.hxx +27 -18
- data/ext/couchbase/couchbase/upsert_options.hxx +3 -3
- data/ext/couchbase/couchbase/vector_query.hxx +1 -1
- data/ext/couchbase/couchbase/wait_until_ready_options.hxx +111 -0
- data/ext/couchbase/couchbase/wildcard_query.hxx +1 -1
- data/ext/extconf.rb +15 -10
- data/ext/rcb_analytics.cxx +82 -102
- data/ext/rcb_backend.cxx +42 -36
- data/ext/rcb_backend.hxx +2 -0
- data/ext/rcb_buckets.cxx +47 -59
- data/ext/rcb_collections.cxx +42 -52
- data/ext/rcb_crud.cxx +345 -224
- data/ext/rcb_diagnostics.cxx +117 -27
- data/ext/rcb_exceptions.cxx +152 -99
- data/ext/rcb_exceptions.hxx +25 -0
- data/ext/rcb_extras.cxx +18 -19
- data/ext/rcb_hdr_histogram.cxx +19 -4
- data/ext/rcb_logger.cxx +202 -27
- data/ext/rcb_logger.hxx +12 -0
- data/ext/rcb_multi.cxx +40 -40
- data/ext/rcb_observability.cxx +7 -5
- data/ext/rcb_query.cxx +99 -142
- data/ext/rcb_range_scan.cxx +41 -35
- data/ext/rcb_search.cxx +98 -99
- data/ext/rcb_users.cxx +36 -56
- data/ext/rcb_utils.cxx +100 -37
- data/ext/rcb_utils.hxx +287 -33
- data/ext/rcb_version.cxx +1 -1
- data/ext/rcb_views.cxx +55 -51
- data/lib/active_support/cache/couchbase_store.rb +77 -12
- data/lib/couchbase/bucket.rb +20 -0
- data/lib/couchbase/cluster.rb +33 -14
- data/lib/couchbase/collection.rb +36 -1
- data/lib/couchbase/errors.rb +18 -0
- data/lib/couchbase/fork_hooks.rb +16 -7
- data/lib/couchbase/get_replica_strategy.rb +89 -0
- data/lib/couchbase/logger.rb +1 -1
- data/lib/couchbase/management/analytics_index_manager.rb +15 -15
- data/lib/couchbase/management/bucket_manager.rb +6 -6
- data/lib/couchbase/management/collection_manager.rb +6 -6
- data/lib/couchbase/management/query_index_manager.rb +7 -7
- data/lib/couchbase/management/search_index_manager.rb +13 -13
- data/lib/couchbase/management/user_manager.rb +10 -10
- data/lib/couchbase/management/view_index_manager.rb +5 -5
- data/lib/couchbase/options.rb +181 -44
- data/lib/couchbase/protostellar/bucket.rb +4 -0
- data/lib/couchbase/protostellar/cluster.rb +4 -0
- data/lib/couchbase/protostellar/collection.rb +4 -0
- data/lib/couchbase/protostellar/error_handling.rb +2 -1
- data/lib/couchbase/protostellar/request.rb +1 -0
- data/lib/couchbase/protostellar/request_generator/kv.rb +16 -2
- data/lib/couchbase/protostellar/request_generator/search.rb +17 -1
- data/lib/couchbase/protostellar/retry/orchestrator.rb +3 -2
- data/lib/couchbase/protostellar/retry/strategies/fail_fast.rb +33 -0
- data/lib/couchbase/protostellar/retry/strategies.rb +1 -0
- data/lib/couchbase/search_options.rb +95 -6
- data/lib/couchbase/version.rb +1 -1
- metadata +92 -33
- data/ext/0001-fix-build-for-mingw-w64-ucrt-x86_64-toolchain.patch +0 -40
- data/ext/couchbase/core/columnar/agent.hxx +0 -71
- data/ext/couchbase/core/columnar/agent_config.hxx +0 -59
- data/ext/couchbase/core/columnar/background_bootstrap_listener.hxx +0 -42
- data/ext/couchbase/core/columnar/backoff_calculator.cxx +0 -62
- data/ext/couchbase/core/columnar/columnar_agent.cxx +0 -147
- data/ext/couchbase/core/columnar/columnar_agent_config.cxx +0 -48
- data/ext/couchbase/core/columnar/columnar_error.cxx +0 -51
- data/ext/couchbase/core/columnar/database_management_options.hxx +0 -56
- data/ext/couchbase/core/columnar/error.hxx +0 -51
- data/ext/couchbase/core/columnar/error_codes.cxx +0 -107
- data/ext/couchbase/core/columnar/error_codes.hxx +0 -75
- data/ext/couchbase/core/columnar/management_component.cxx +0 -300
- data/ext/couchbase/core/columnar/management_component.hxx +0 -56
- data/ext/couchbase/core/columnar/query_component.cxx +0 -523
- data/ext/couchbase/core/columnar/query_component.hxx +0 -57
- data/ext/couchbase/core/columnar/query_options.hxx +0 -59
- data/ext/couchbase/core/columnar/query_result.cxx +0 -130
- data/ext/couchbase/core/columnar/query_result.hxx +0 -78
- data/ext/couchbase/core/io/config_tracker.cxx +0 -687
- data/ext/couchbase/core/io/config_tracker.hxx +0 -123
|
@@ -19,10 +19,11 @@
|
|
|
19
19
|
|
|
20
20
|
#include "free_form_http_request.hxx"
|
|
21
21
|
#include "io/http_session_manager.hxx"
|
|
22
|
+
#include "logger/redaction.hxx"
|
|
22
23
|
#include "pending_operation.hxx"
|
|
23
24
|
#include "pending_operation_connection_info.hxx"
|
|
24
|
-
|
|
25
|
-
#include
|
|
25
|
+
#include "tracing/constants.hxx"
|
|
26
|
+
#include "tracing/tracer_wrapper.hxx"
|
|
26
27
|
|
|
27
28
|
#include <asio/error.hpp>
|
|
28
29
|
#include <spdlog/fmt/bundled/chrono.h>
|
|
@@ -50,25 +51,12 @@ class pending_http_operation
|
|
|
50
51
|
, public pending_operation_connection_info
|
|
51
52
|
{
|
|
52
53
|
public:
|
|
53
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
54
|
-
pending_http_operation(asio::io_context& io,
|
|
55
|
-
http_request request,
|
|
56
|
-
std::chrono::milliseconds dispatch_timeout)
|
|
57
|
-
: deadline_{ io }
|
|
58
|
-
, dispatch_deadline_{ io }
|
|
59
|
-
, dispatch_timeout_{ dispatch_timeout }
|
|
60
|
-
, request_{ std::move(request) }
|
|
61
|
-
, encoded_{ encode_http_request(request_) }
|
|
62
|
-
{
|
|
63
|
-
}
|
|
64
|
-
#else
|
|
65
54
|
pending_http_operation(asio::io_context& io, http_request request)
|
|
66
55
|
: deadline_{ io }
|
|
67
56
|
, request_{ std::move(request) }
|
|
68
57
|
, encoded_{ encode_http_request(request_) }
|
|
69
58
|
{
|
|
70
59
|
}
|
|
71
|
-
#endif
|
|
72
60
|
|
|
73
61
|
~pending_http_operation() override = default;
|
|
74
62
|
pending_http_operation(const pending_http_operation&) = delete;
|
|
@@ -80,107 +68,112 @@ public:
|
|
|
80
68
|
{
|
|
81
69
|
callback_ = std::move(callback);
|
|
82
70
|
encoded_.headers["client-context-id"] = request_.client_context_id;
|
|
83
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
84
|
-
dispatch_deadline_.expires_after(dispatch_timeout_);
|
|
85
|
-
dispatch_deadline_.async_wait([self = shared_from_this()](auto ec) {
|
|
86
|
-
if (ec == asio::error::operation_aborted) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
CB_LOG_DEBUG(
|
|
90
|
-
R"(HTTP request timed out (dispatch): {}, method={}, path="{}", dispatch_timeout={}, client_context_id={})",
|
|
91
|
-
self->encoded_.type,
|
|
92
|
-
self->encoded_.method,
|
|
93
|
-
self->encoded_.path,
|
|
94
|
-
self->dispatch_timeout_,
|
|
95
|
-
self->encoded_.client_context_id);
|
|
96
|
-
self->trigger_timeout();
|
|
97
|
-
if (self->session_) {
|
|
98
|
-
self->session_->stop();
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
#endif
|
|
102
71
|
deadline_.expires_after(request_.timeout);
|
|
103
72
|
deadline_.async_wait([self = shared_from_this()](auto ec) {
|
|
104
73
|
if (ec == asio::error::operation_aborted) {
|
|
105
74
|
return;
|
|
106
75
|
}
|
|
76
|
+
// deadline_.cancel() does not retract a completion already queued. A response that took
|
|
77
|
+
// the callback first has handed the session to the stream or to the pool.
|
|
78
|
+
if (!self->trigger_timeout()) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
107
81
|
CB_LOG_DEBUG(
|
|
108
82
|
R"(HTTP request timed out: {}, method={}, path="{}", timeout={}, client_context_id={})",
|
|
109
83
|
self->encoded_.type,
|
|
110
84
|
self->encoded_.method,
|
|
111
|
-
self->encoded_.path,
|
|
85
|
+
logger::user_data(self->encoded_.path),
|
|
112
86
|
self->request_.timeout,
|
|
113
87
|
self->encoded_.client_context_id);
|
|
114
|
-
self->trigger_timeout();
|
|
115
|
-
if (self->session_) {
|
|
116
|
-
self->session_->stop();
|
|
117
|
-
}
|
|
118
88
|
});
|
|
119
89
|
}
|
|
120
90
|
|
|
121
|
-
|
|
91
|
+
// Receives the session the stream was dispatched on, which a failover makes different from the
|
|
92
|
+
// one checked out.
|
|
93
|
+
void set_stream_end_callback(
|
|
94
|
+
utils::movable_function<void(std::shared_ptr<io::http_session>)>&& stream_end_callback)
|
|
122
95
|
{
|
|
123
96
|
stream_end_callback_ = std::move(stream_end_callback);
|
|
124
97
|
}
|
|
125
98
|
|
|
99
|
+
void set_tracer(std::shared_ptr<tracing::tracer_wrapper> tracer)
|
|
100
|
+
{
|
|
101
|
+
tracer_ = std::move(tracer);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Once the stream has ended its connection is back in the pool, possibly serving another
|
|
105
|
+
// request, so cancel() leaves it alone. A cancel that comes first keeps the stream end from
|
|
106
|
+
// checking the connection in.
|
|
126
107
|
void cancel() override
|
|
127
108
|
{
|
|
128
|
-
|
|
129
|
-
|
|
109
|
+
std::shared_ptr<io::http_session> session;
|
|
110
|
+
{
|
|
111
|
+
const std::scoped_lock lock(callback_mutex_);
|
|
112
|
+
if (stream_ended_) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
cancelled_ = true;
|
|
116
|
+
session = session_.lock();
|
|
117
|
+
}
|
|
118
|
+
if (session) {
|
|
119
|
+
session->stop();
|
|
130
120
|
}
|
|
131
121
|
invoke_response_handler(errc::common::request_canceled, {});
|
|
132
122
|
}
|
|
133
123
|
|
|
134
|
-
|
|
135
|
-
|
|
124
|
+
// Returns whether this call took the callback, which is the token for completing the request.
|
|
125
|
+
auto invoke_response_handler(std::error_code err, io::http_streaming_response resp) -> bool
|
|
136
126
|
{
|
|
137
|
-
dispatch_deadline_.cancel();
|
|
138
|
-
#else
|
|
139
|
-
void invoke_response_handler(std::error_code err, io::http_streaming_response resp)
|
|
140
|
-
{
|
|
141
|
-
#endif
|
|
142
127
|
deadline_.cancel();
|
|
143
128
|
free_form_http_request_callback callback{};
|
|
129
|
+
std::shared_ptr<couchbase::tracing::request_span> dispatch_span{};
|
|
144
130
|
{
|
|
145
131
|
const std::scoped_lock lock(callback_mutex_);
|
|
146
132
|
std::swap(callback, callback_);
|
|
133
|
+
std::swap(dispatch_span, dispatch_span_);
|
|
134
|
+
}
|
|
135
|
+
// The dispatch span covers the request up to the response headers, not the streamed body.
|
|
136
|
+
if (dispatch_span) {
|
|
137
|
+
dispatch_span->end();
|
|
147
138
|
}
|
|
148
|
-
if (callback) {
|
|
149
|
-
|
|
139
|
+
if (!callback) {
|
|
140
|
+
return false;
|
|
150
141
|
}
|
|
142
|
+
callback(http_response{ std::move(resp) }, err);
|
|
143
|
+
return true;
|
|
151
144
|
}
|
|
152
145
|
|
|
153
146
|
void send_to(std::shared_ptr<io::http_session> session)
|
|
154
147
|
{
|
|
155
|
-
|
|
156
|
-
|
|
148
|
+
{
|
|
149
|
+
// The deadline or a cancel can complete the operation concurrently. Checking the callback and
|
|
150
|
+
// storing the span under the lock that invoke_response_handler takes means the span is either
|
|
151
|
+
// stored before the handler runs, and ended by it, or never created.
|
|
152
|
+
std::unique_lock lock(callback_mutex_);
|
|
153
|
+
if (!callback_) {
|
|
154
|
+
// The session is listed busy and nothing checks it in; on_stop removes it.
|
|
155
|
+
lock.unlock();
|
|
156
|
+
return session->stop();
|
|
157
|
+
}
|
|
158
|
+
session_ = session;
|
|
159
|
+
dispatched_to_ = session->remote_address();
|
|
160
|
+
dispatched_from_ = session->local_address();
|
|
161
|
+
dispatched_to_host_ = fmt::format("{}:{}", session->hostname(), session->port());
|
|
162
|
+
dispatch_span_ = create_dispatch_span(*session);
|
|
157
163
|
}
|
|
158
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
159
|
-
dispatch_deadline_.cancel();
|
|
160
|
-
#endif
|
|
161
|
-
session_ = std::move(session);
|
|
162
164
|
|
|
163
|
-
auto start_op = [self = shared_from_this()]() {
|
|
164
|
-
|
|
165
|
+
auto start_op = [self = shared_from_this(), session]() {
|
|
166
|
+
session->write_and_stream(
|
|
165
167
|
self->encoded_,
|
|
166
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
167
|
-
[self](error_union err, io::http_streaming_response resp) {
|
|
168
|
-
if (std::holds_alternative<std::error_code>(err) &&
|
|
169
|
-
std::get<std::error_code>(err) == asio::error::operation_aborted) {
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
self->invoke_response_handler(err, std::move(resp));
|
|
173
|
-
},
|
|
174
|
-
#else
|
|
175
168
|
[self](std::error_code ec, io::http_streaming_response resp) {
|
|
176
169
|
if (ec == asio::error::operation_aborted) {
|
|
177
170
|
return;
|
|
178
171
|
}
|
|
172
|
+
self->refresh_dispatched();
|
|
179
173
|
self->invoke_response_handler(ec, std::move(resp));
|
|
180
174
|
},
|
|
181
|
-
#endif
|
|
182
175
|
[self]() {
|
|
183
|
-
self->stream_end_callback_();
|
|
176
|
+
self->stream_end_callback_(self->session_at_stream_end());
|
|
184
177
|
});
|
|
185
178
|
};
|
|
186
179
|
|
|
@@ -192,14 +185,6 @@ public:
|
|
|
192
185
|
return deadline_.expiry();
|
|
193
186
|
}
|
|
194
187
|
|
|
195
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
196
|
-
[[nodiscard]] auto dispatch_deadline_expiry() const
|
|
197
|
-
-> std::chrono::time_point<std::chrono::steady_clock>
|
|
198
|
-
{
|
|
199
|
-
return dispatch_deadline_.expiry();
|
|
200
|
-
}
|
|
201
|
-
#endif
|
|
202
|
-
|
|
203
188
|
[[nodiscard]] auto request() const -> http_request
|
|
204
189
|
{
|
|
205
190
|
return request_;
|
|
@@ -207,40 +192,137 @@ public:
|
|
|
207
192
|
|
|
208
193
|
[[nodiscard]] auto dispatched_to() const -> std::string override
|
|
209
194
|
{
|
|
210
|
-
|
|
195
|
+
const std::scoped_lock lock(callback_mutex_);
|
|
196
|
+
return dispatched_to_;
|
|
211
197
|
}
|
|
212
198
|
|
|
213
199
|
[[nodiscard]] auto dispatched_from() const -> std::string override
|
|
214
200
|
{
|
|
215
|
-
|
|
201
|
+
const std::scoped_lock lock(callback_mutex_);
|
|
202
|
+
return dispatched_from_;
|
|
216
203
|
}
|
|
217
204
|
|
|
218
205
|
[[nodiscard]] auto dispatched_to_host() const -> std::string override
|
|
219
206
|
{
|
|
220
|
-
|
|
207
|
+
const std::scoped_lock lock(callback_mutex_);
|
|
208
|
+
return dispatched_to_host_;
|
|
221
209
|
}
|
|
222
210
|
|
|
223
211
|
private:
|
|
224
|
-
|
|
212
|
+
// Rereads the endpoints from the session. A resend after a refused client certificate writes the
|
|
213
|
+
// request on a new connection.
|
|
214
|
+
void refresh_dispatched()
|
|
215
|
+
{
|
|
216
|
+
const std::scoped_lock lock(callback_mutex_);
|
|
217
|
+
if (const auto session = session_.lock(); session) {
|
|
218
|
+
if (auto [from, to] = session->dispatched_endpoints(); !to.empty()) {
|
|
219
|
+
dispatched_from_ = std::move(from);
|
|
220
|
+
dispatched_to_ = std::move(to);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Null before send_to() runs or once the session is gone: the operation does not keep its
|
|
226
|
+
// session alive.
|
|
227
|
+
[[nodiscard]] auto session() const -> std::shared_ptr<io::http_session>
|
|
228
|
+
{
|
|
229
|
+
const std::scoped_lock lock(callback_mutex_);
|
|
230
|
+
return session_.lock();
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// The session to check in at stream end: null if cancel() or the deadline came first, which stops
|
|
234
|
+
// it.
|
|
235
|
+
[[nodiscard]] auto session_at_stream_end() -> std::shared_ptr<io::http_session>
|
|
225
236
|
{
|
|
237
|
+
const std::scoped_lock lock(callback_mutex_);
|
|
238
|
+
stream_ended_ = true;
|
|
239
|
+
if (cancelled_) {
|
|
240
|
+
return nullptr;
|
|
241
|
+
}
|
|
242
|
+
return session_.lock();
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Ends the request with a timeout unless a response took the callback first. The session is
|
|
246
|
+
// stopped before the callback runs, and a stream end does not check it in. Returns whether this
|
|
247
|
+
// call took the callback.
|
|
248
|
+
auto trigger_timeout() -> bool
|
|
249
|
+
{
|
|
250
|
+
refresh_dispatched();
|
|
226
251
|
// TODO(JC): if triggered from the dispatch timeout, should only be
|
|
227
252
|
// errc::common::unambiguous_timeout?
|
|
228
253
|
auto ec =
|
|
229
254
|
request_.is_read_only ? errc::common::unambiguous_timeout : errc::common::ambiguous_timeout;
|
|
230
|
-
|
|
255
|
+
free_form_http_request_callback callback{};
|
|
256
|
+
std::shared_ptr<couchbase::tracing::request_span> dispatch_span{};
|
|
257
|
+
std::shared_ptr<io::http_session> session;
|
|
258
|
+
{
|
|
259
|
+
const std::scoped_lock lock(callback_mutex_);
|
|
260
|
+
std::swap(callback, callback_);
|
|
261
|
+
std::swap(dispatch_span, dispatch_span_);
|
|
262
|
+
if (callback) {
|
|
263
|
+
cancelled_ = true;
|
|
264
|
+
}
|
|
265
|
+
session = session_.lock();
|
|
266
|
+
}
|
|
267
|
+
if (dispatch_span) {
|
|
268
|
+
dispatch_span->end();
|
|
269
|
+
}
|
|
270
|
+
if (!callback) {
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
if (session) {
|
|
274
|
+
session->stop();
|
|
275
|
+
}
|
|
276
|
+
callback(http_response{ io::http_streaming_response{} }, ec);
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Carries the same tags as http_command::create_dispatch_span, so a streamed request reports the
|
|
281
|
+
// same dispatch_to_server span as a buffered one. It is parented to the caller's span because no
|
|
282
|
+
// operation span exists in core for a streamed request.
|
|
283
|
+
[[nodiscard]] auto create_dispatch_span(io::http_session& session) const
|
|
284
|
+
-> std::shared_ptr<couchbase::tracing::request_span>
|
|
285
|
+
{
|
|
286
|
+
if (!tracer_) {
|
|
287
|
+
return {};
|
|
288
|
+
}
|
|
289
|
+
auto dispatch_span =
|
|
290
|
+
tracer_->create_span(tracing::operation::step_dispatch, request_.parent_span);
|
|
291
|
+
if (dispatch_span->uses_tags()) {
|
|
292
|
+
dispatch_span->add_tag(tracing::attributes::dispatch::network_transport, "tcp");
|
|
293
|
+
dispatch_span->add_tag(tracing::attributes::dispatch::operation_id,
|
|
294
|
+
request_.client_context_id);
|
|
295
|
+
dispatch_span->add_tag(tracing::attributes::dispatch::local_id, session.id());
|
|
296
|
+
dispatch_span->add_tag(tracing::attributes::dispatch::server_address,
|
|
297
|
+
session.http_context().canonical_hostname);
|
|
298
|
+
dispatch_span->add_tag(tracing::attributes::dispatch::server_port,
|
|
299
|
+
session.http_context().canonical_port);
|
|
300
|
+
|
|
301
|
+
const auto& peer_endpoint = session.remote_endpoint();
|
|
302
|
+
dispatch_span->add_tag(tracing::attributes::dispatch::peer_address,
|
|
303
|
+
peer_endpoint.address().to_string());
|
|
304
|
+
dispatch_span->add_tag(tracing::attributes::dispatch::peer_port, peer_endpoint.port());
|
|
305
|
+
}
|
|
306
|
+
return dispatch_span;
|
|
231
307
|
}
|
|
232
308
|
|
|
233
309
|
asio::steady_timer deadline_;
|
|
234
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
235
|
-
asio::steady_timer dispatch_deadline_;
|
|
236
|
-
std::chrono::milliseconds dispatch_timeout_;
|
|
237
|
-
#endif
|
|
238
310
|
http_request request_;
|
|
239
311
|
io::http_request encoded_;
|
|
240
312
|
free_form_http_request_callback callback_;
|
|
241
|
-
|
|
242
|
-
std::shared_ptr<
|
|
243
|
-
std::
|
|
313
|
+
std::shared_ptr<tracing::tracer_wrapper> tracer_{};
|
|
314
|
+
std::shared_ptr<couchbase::tracing::request_span> dispatch_span_{};
|
|
315
|
+
utils::movable_function<void(std::shared_ptr<io::http_session>)> stream_end_callback_;
|
|
316
|
+
std::weak_ptr<io::http_session> session_;
|
|
317
|
+
// Endpoints of the session send_to() dispatched on, guarded by callback_mutex_. Recorded because
|
|
318
|
+
// session_ expires once the session is released.
|
|
319
|
+
std::string dispatched_to_;
|
|
320
|
+
std::string dispatched_from_;
|
|
321
|
+
std::string dispatched_to_host_;
|
|
322
|
+
// Guarded by callback_mutex_.
|
|
323
|
+
bool stream_ended_{ false };
|
|
324
|
+
bool cancelled_{ false };
|
|
325
|
+
mutable std::mutex callback_mutex_;
|
|
244
326
|
};
|
|
245
327
|
|
|
246
328
|
class pending_buffered_http_operation
|
|
@@ -249,25 +331,12 @@ class pending_buffered_http_operation
|
|
|
249
331
|
, public pending_operation_connection_info
|
|
250
332
|
{
|
|
251
333
|
public:
|
|
252
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
253
|
-
pending_buffered_http_operation(asio::io_context& io,
|
|
254
|
-
http_request request,
|
|
255
|
-
std::chrono::milliseconds dispatch_timeout)
|
|
256
|
-
: deadline_{ io }
|
|
257
|
-
, dispatch_deadline_{ io }
|
|
258
|
-
, dispatch_timeout_{ dispatch_timeout }
|
|
259
|
-
, request_{ std::move(request) }
|
|
260
|
-
, encoded_{ encode_http_request(request_) }
|
|
261
|
-
{
|
|
262
|
-
}
|
|
263
|
-
#else
|
|
264
334
|
pending_buffered_http_operation(asio::io_context& io, http_request request)
|
|
265
335
|
: deadline_{ io }
|
|
266
336
|
, request_{ std::move(request) }
|
|
267
337
|
, encoded_{ encode_http_request(request_) }
|
|
268
338
|
{
|
|
269
339
|
}
|
|
270
|
-
#endif
|
|
271
340
|
|
|
272
341
|
~pending_buffered_http_operation() override = default;
|
|
273
342
|
pending_buffered_http_operation(const pending_buffered_http_operation&) = delete;
|
|
@@ -280,99 +349,106 @@ public:
|
|
|
280
349
|
{
|
|
281
350
|
callback_ = std::move(callback);
|
|
282
351
|
encoded_.headers["client-context-id"] = request_.client_context_id;
|
|
283
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
284
|
-
dispatch_deadline_.expires_after(dispatch_timeout_);
|
|
285
|
-
dispatch_deadline_.async_wait([self = shared_from_this()](auto ec) {
|
|
286
|
-
if (ec == asio::error::operation_aborted) {
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
CB_LOG_DEBUG(
|
|
290
|
-
R"(HTTP request timed out (dispatch): {}, method={}, path="{}", dispatch_timeout={}, client_context_id={})",
|
|
291
|
-
self->encoded_.type,
|
|
292
|
-
self->encoded_.method,
|
|
293
|
-
self->encoded_.path,
|
|
294
|
-
self->dispatch_timeout_,
|
|
295
|
-
self->encoded_.client_context_id);
|
|
296
|
-
self->trigger_timeout();
|
|
297
|
-
if (self->session_) {
|
|
298
|
-
self->session_->stop();
|
|
299
|
-
}
|
|
300
|
-
});
|
|
301
|
-
#endif
|
|
302
352
|
deadline_.expires_after(request_.timeout);
|
|
303
353
|
deadline_.async_wait([self = shared_from_this()](auto ec) {
|
|
304
354
|
if (ec == asio::error::operation_aborted) {
|
|
305
355
|
return;
|
|
306
356
|
}
|
|
357
|
+
// deadline_.cancel() does not retract a completion already queued. A response that took
|
|
358
|
+
// the callback first has handed the session back to the pool.
|
|
359
|
+
if (!self->trigger_timeout()) {
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
307
362
|
CB_LOG_DEBUG(
|
|
308
363
|
R"(HTTP request timed out: {}, method={}, path="{}", timeout={}, client_context_id={})",
|
|
309
364
|
self->encoded_.type,
|
|
310
365
|
self->encoded_.method,
|
|
311
|
-
self->encoded_.path,
|
|
366
|
+
logger::user_data(self->encoded_.path),
|
|
312
367
|
self->request_.timeout,
|
|
313
368
|
self->encoded_.client_context_id);
|
|
314
|
-
self->trigger_timeout();
|
|
315
|
-
if (self->session_) {
|
|
316
|
-
self->session_->stop();
|
|
317
|
-
}
|
|
318
369
|
});
|
|
319
370
|
}
|
|
320
371
|
|
|
372
|
+
// Takes the callback, then stops the session before running it: the callback checks the session
|
|
373
|
+
// in, and check_in refuses a stopped one. With no callback left the operation has completed, and
|
|
374
|
+
// its connection may be serving another request.
|
|
321
375
|
void cancel() override
|
|
322
376
|
{
|
|
323
|
-
|
|
324
|
-
|
|
377
|
+
buffered_free_form_http_request_callback callback{};
|
|
378
|
+
std::shared_ptr<io::http_session> session;
|
|
379
|
+
{
|
|
380
|
+
const std::scoped_lock lock(callback_mutex_);
|
|
381
|
+
std::swap(callback, callback_);
|
|
382
|
+
session = session_.lock();
|
|
325
383
|
}
|
|
326
|
-
|
|
384
|
+
if (!callback) {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
deadline_.cancel();
|
|
388
|
+
if (session) {
|
|
389
|
+
session->stop();
|
|
390
|
+
}
|
|
391
|
+
callback(buffered_http_response{ io::http_response{} }, errc::common::request_canceled);
|
|
327
392
|
}
|
|
328
393
|
|
|
329
|
-
|
|
394
|
+
// Returns whether this call took the callback, which is the token for completing the request.
|
|
395
|
+
auto invoke_response_handler(std::error_code ec, io::http_response resp) -> bool
|
|
330
396
|
{
|
|
331
397
|
deadline_.cancel();
|
|
332
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
333
|
-
dispatch_deadline_.cancel();
|
|
334
|
-
#endif
|
|
335
398
|
buffered_free_form_http_request_callback callback{};
|
|
336
399
|
{
|
|
337
400
|
const std::scoped_lock lock(callback_mutex_);
|
|
338
401
|
std::swap(callback, callback_);
|
|
339
402
|
}
|
|
340
|
-
if (callback) {
|
|
341
|
-
|
|
403
|
+
if (!callback) {
|
|
404
|
+
return false;
|
|
342
405
|
}
|
|
406
|
+
callback(buffered_http_response{ std::move(resp) }, ec);
|
|
407
|
+
return true;
|
|
343
408
|
}
|
|
344
409
|
|
|
345
410
|
void send_to(std::shared_ptr<io::http_session> session)
|
|
346
411
|
{
|
|
347
|
-
|
|
348
|
-
|
|
412
|
+
{
|
|
413
|
+
// Checked and stored under the lock invoke_response_handler takes the callback with: a
|
|
414
|
+
// deadline completion that took the callback reads this session, and after it took the
|
|
415
|
+
// callback nothing is stored.
|
|
416
|
+
std::unique_lock lock(callback_mutex_);
|
|
417
|
+
if (!callback_) {
|
|
418
|
+
// The completion checks in only a session stored here, so this one stays listed busy
|
|
419
|
+
// until on_stop removes it.
|
|
420
|
+
lock.unlock();
|
|
421
|
+
return session->stop();
|
|
422
|
+
}
|
|
423
|
+
session_ = session;
|
|
424
|
+
dispatched_to_ = session->remote_address();
|
|
425
|
+
dispatched_from_ = session->local_address();
|
|
426
|
+
dispatched_to_host_ = fmt::format("{}:{}", session->hostname(), session->port());
|
|
349
427
|
}
|
|
350
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
351
|
-
dispatch_deadline_.cancel();
|
|
352
|
-
#endif
|
|
353
|
-
session_ = std::move(session);
|
|
354
428
|
|
|
355
|
-
|
|
429
|
+
session->write_and_subscribe(
|
|
356
430
|
encoded_, [self = shared_from_this()](std::error_code ec, io::http_response resp) {
|
|
357
431
|
if (ec == asio::error::operation_aborted) {
|
|
358
432
|
return;
|
|
359
433
|
}
|
|
434
|
+
self->refresh_dispatched();
|
|
360
435
|
self->invoke_response_handler(ec, std::move(resp));
|
|
361
436
|
});
|
|
362
437
|
}
|
|
363
438
|
|
|
364
|
-
|
|
439
|
+
// The session send_to() dispatched on, which a failover makes different from the one checked
|
|
440
|
+
// out. Null if send_to() never ran or the session is gone: the operation does not keep its
|
|
441
|
+
// session alive.
|
|
442
|
+
[[nodiscard]] auto session() const -> std::shared_ptr<io::http_session>
|
|
365
443
|
{
|
|
366
|
-
|
|
444
|
+
const std::scoped_lock lock(callback_mutex_);
|
|
445
|
+
return session_.lock();
|
|
367
446
|
}
|
|
368
447
|
|
|
369
|
-
|
|
370
|
-
[[nodiscard]] auto dispatch_deadline_expiry() const
|
|
371
|
-
-> std::chrono::time_point<std::chrono::steady_clock>
|
|
448
|
+
[[nodiscard]] auto deadline_expiry() const -> std::chrono::time_point<std::chrono::steady_clock>
|
|
372
449
|
{
|
|
373
|
-
return
|
|
450
|
+
return deadline_.expiry();
|
|
374
451
|
}
|
|
375
|
-
#endif
|
|
376
452
|
|
|
377
453
|
[[nodiscard]] auto request() const -> http_request
|
|
378
454
|
{
|
|
@@ -381,39 +457,74 @@ public:
|
|
|
381
457
|
|
|
382
458
|
[[nodiscard]] auto dispatched_to() const -> std::string override
|
|
383
459
|
{
|
|
384
|
-
|
|
460
|
+
const std::scoped_lock lock(callback_mutex_);
|
|
461
|
+
return dispatched_to_;
|
|
385
462
|
}
|
|
386
463
|
|
|
387
464
|
[[nodiscard]] auto dispatched_from() const -> std::string override
|
|
388
465
|
{
|
|
389
|
-
|
|
466
|
+
const std::scoped_lock lock(callback_mutex_);
|
|
467
|
+
return dispatched_from_;
|
|
390
468
|
}
|
|
391
469
|
|
|
392
470
|
[[nodiscard]] auto dispatched_to_host() const -> std::string override
|
|
393
471
|
{
|
|
394
|
-
|
|
472
|
+
const std::scoped_lock lock(callback_mutex_);
|
|
473
|
+
return dispatched_to_host_;
|
|
395
474
|
}
|
|
396
475
|
|
|
397
476
|
private:
|
|
398
|
-
|
|
477
|
+
// Rereads the endpoints from the session. A resend after a refused client certificate writes the
|
|
478
|
+
// request on a new connection.
|
|
479
|
+
void refresh_dispatched()
|
|
480
|
+
{
|
|
481
|
+
const std::scoped_lock lock(callback_mutex_);
|
|
482
|
+
if (const auto session = session_.lock(); session) {
|
|
483
|
+
if (auto [from, to] = session->dispatched_endpoints(); !to.empty()) {
|
|
484
|
+
dispatched_from_ = std::move(from);
|
|
485
|
+
dispatched_to_ = std::move(to);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// Ends the request with a timeout unless a response took the callback first. The session is
|
|
491
|
+
// stopped before the callback runs: the callback checks the session in, and check_in refuses a
|
|
492
|
+
// stopped one. Returns whether this call took the callback.
|
|
493
|
+
auto trigger_timeout() -> bool
|
|
399
494
|
{
|
|
495
|
+
refresh_dispatched();
|
|
400
496
|
// TODO(JC): if triggered from the dispatch timeout, should only be
|
|
401
497
|
// errc::common::unambiguous_timeout?
|
|
402
498
|
auto ec =
|
|
403
499
|
request_.is_read_only ? errc::common::unambiguous_timeout : errc::common::ambiguous_timeout;
|
|
404
|
-
|
|
500
|
+
buffered_free_form_http_request_callback callback{};
|
|
501
|
+
std::shared_ptr<io::http_session> session;
|
|
502
|
+
{
|
|
503
|
+
const std::scoped_lock lock(callback_mutex_);
|
|
504
|
+
std::swap(callback, callback_);
|
|
505
|
+
session = session_.lock();
|
|
506
|
+
}
|
|
507
|
+
if (!callback) {
|
|
508
|
+
return false;
|
|
509
|
+
}
|
|
510
|
+
if (session) {
|
|
511
|
+
session->stop();
|
|
512
|
+
}
|
|
513
|
+
callback(buffered_http_response{ io::http_response{} }, ec);
|
|
514
|
+
return true;
|
|
405
515
|
}
|
|
406
516
|
|
|
407
517
|
asio::steady_timer deadline_;
|
|
408
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
409
|
-
asio::steady_timer dispatch_deadline_;
|
|
410
|
-
std::chrono::milliseconds dispatch_timeout_;
|
|
411
|
-
#endif
|
|
412
518
|
http_request request_;
|
|
413
519
|
io::http_request encoded_;
|
|
414
520
|
buffered_free_form_http_request_callback callback_;
|
|
415
|
-
std::
|
|
416
|
-
|
|
521
|
+
std::weak_ptr<io::http_session> session_;
|
|
522
|
+
// Endpoints of the session send_to() dispatched on, guarded by callback_mutex_. Recorded because
|
|
523
|
+
// session_ expires once the session is released.
|
|
524
|
+
std::string dispatched_to_;
|
|
525
|
+
std::string dispatched_from_;
|
|
526
|
+
std::string dispatched_to_host_;
|
|
527
|
+
mutable std::mutex callback_mutex_;
|
|
417
528
|
};
|
|
418
529
|
|
|
419
530
|
class http_component_impl
|
|
@@ -428,13 +539,8 @@ public:
|
|
|
428
539
|
{
|
|
429
540
|
}
|
|
430
541
|
|
|
431
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
432
|
-
auto do_http_request(const http_request& request, free_form_http_request_callback&& callback)
|
|
433
|
-
-> tl::expected<std::shared_ptr<pending_operation>, error_union>
|
|
434
|
-
#else
|
|
435
542
|
auto do_http_request(const http_request& request, free_form_http_request_callback&& callback)
|
|
436
543
|
-> tl::expected<std::shared_ptr<pending_operation>, std::error_code>
|
|
437
|
-
#endif
|
|
438
544
|
{
|
|
439
545
|
std::shared_ptr<io::http_session_manager> session_manager;
|
|
440
546
|
{
|
|
@@ -444,19 +550,7 @@ public:
|
|
|
444
550
|
}
|
|
445
551
|
session_manager = std::move(sm);
|
|
446
552
|
}
|
|
447
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
448
|
-
auto op =
|
|
449
|
-
std::make_shared<pending_http_operation>(io_, request, session_manager->dispatch_timeout());
|
|
450
|
-
if (!session_manager->is_configured()) {
|
|
451
|
-
auto err = defer_command(op, session_manager, std::move(callback));
|
|
452
|
-
if (!std::holds_alternative<std::monostate>(err)) {
|
|
453
|
-
return tl::unexpected{ err };
|
|
454
|
-
}
|
|
455
|
-
return op;
|
|
456
|
-
}
|
|
457
|
-
#else
|
|
458
553
|
auto op = std::make_shared<pending_http_operation>(io_, request);
|
|
459
|
-
#endif
|
|
460
554
|
|
|
461
555
|
send_http_operation(op, session_manager, std::move(callback));
|
|
462
556
|
return op;
|
|
@@ -475,22 +569,7 @@ public:
|
|
|
475
569
|
session_manager = std::move(sm);
|
|
476
570
|
}
|
|
477
571
|
|
|
478
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
479
|
-
auto op = std::make_shared<pending_buffered_http_operation>(
|
|
480
|
-
io_, request, session_manager->dispatch_timeout());
|
|
481
|
-
if (!session_manager->is_configured()) {
|
|
482
|
-
auto err = defer_command(op, session_manager, std::move(callback));
|
|
483
|
-
if (!std::holds_alternative<std::monostate>(err)) {
|
|
484
|
-
auto ec = std::holds_alternative<impl::bootstrap_error>(err)
|
|
485
|
-
? std::get<impl::bootstrap_error>(err).ec
|
|
486
|
-
: std::get<std::error_code>(err);
|
|
487
|
-
return tl::unexpected{ ec };
|
|
488
|
-
}
|
|
489
|
-
return op;
|
|
490
|
-
}
|
|
491
|
-
#else
|
|
492
572
|
auto op = std::make_shared<pending_buffered_http_operation>(io_, request);
|
|
493
|
-
#endif
|
|
494
573
|
|
|
495
574
|
send_http_operation(op, session_manager, std::move(callback));
|
|
496
575
|
return op;
|
|
@@ -501,44 +580,38 @@ private:
|
|
|
501
580
|
const std::shared_ptr<io::http_session_manager>& session_manager,
|
|
502
581
|
free_form_http_request_callback&& callback)
|
|
503
582
|
{
|
|
504
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
505
|
-
op->start([callback = std::move(callback)](auto resp, error_union err) mutable {
|
|
506
|
-
callback(std::move(resp), err);
|
|
507
|
-
});
|
|
508
|
-
// don't do anything if the op wasn't dispatched or has already timed out
|
|
509
|
-
auto now = std::chrono::steady_clock::now();
|
|
510
|
-
if (op->dispatch_deadline_expiry() < now || op->deadline_expiry() < now) {
|
|
511
|
-
return;
|
|
512
|
-
}
|
|
513
|
-
#else
|
|
514
583
|
op->start([callback = std::move(callback)](auto resp, auto ec) mutable {
|
|
515
584
|
callback(std::move(resp), ec);
|
|
516
585
|
});
|
|
517
|
-
#endif
|
|
518
586
|
std::shared_ptr<io::http_session> session;
|
|
519
587
|
{
|
|
520
588
|
auto [check_out_ec, s] = session_manager->check_out(
|
|
521
589
|
op->request().service, op->request().endpoint, op->request().internal.undesired_endpoint);
|
|
522
590
|
if (check_out_ec) {
|
|
523
|
-
|
|
591
|
+
op->invoke_response_handler(check_out_ec, {});
|
|
592
|
+
return;
|
|
524
593
|
}
|
|
525
594
|
session = std::move(s);
|
|
526
595
|
}
|
|
596
|
+
// Not an owner: a completed operation that never reaches the stream end must not keep the
|
|
597
|
+
// manager alive.
|
|
527
598
|
op->set_stream_end_callback(
|
|
528
|
-
[
|
|
529
|
-
|
|
599
|
+
[manager = std::weak_ptr{ session_manager },
|
|
600
|
+
service = op->request().service](std::shared_ptr<io::http_session> served) {
|
|
601
|
+
if (const auto m = manager.lock(); m) {
|
|
602
|
+
m->check_in(service, std::move(served));
|
|
603
|
+
}
|
|
530
604
|
});
|
|
605
|
+
op->set_tracer(session_manager->tracer());
|
|
531
606
|
if (!session->is_connected()) {
|
|
532
607
|
session_manager->connect_then_send_pending_op(
|
|
533
608
|
session,
|
|
534
609
|
{},
|
|
535
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
536
|
-
op->dispatch_deadline_expiry(),
|
|
537
|
-
#endif
|
|
538
610
|
op->deadline_expiry(),
|
|
539
611
|
[op](std::error_code ec, std::shared_ptr<io::http_session> http_session) {
|
|
540
612
|
if (ec) {
|
|
541
|
-
|
|
613
|
+
op->invoke_response_handler(ec, {});
|
|
614
|
+
return;
|
|
542
615
|
}
|
|
543
616
|
op->send_to(std::move(http_session));
|
|
544
617
|
});
|
|
@@ -556,28 +629,33 @@ private:
|
|
|
556
629
|
auto [check_out_ec, s] = session_manager->check_out(
|
|
557
630
|
op->request().service, op->request().endpoint, op->request().internal.undesired_endpoint);
|
|
558
631
|
if (check_out_ec) {
|
|
559
|
-
|
|
632
|
+
op->invoke_response_handler(check_out_ec, {});
|
|
633
|
+
return;
|
|
560
634
|
}
|
|
561
635
|
session = std::move(s);
|
|
562
636
|
}
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
637
|
+
// Checks in only the session send_to() stored. A completion before send_to() leaves the
|
|
638
|
+
// checked-out session to send_to(), which stops it. Checked in here, it could be taken by
|
|
639
|
+
// another request before that stop.
|
|
640
|
+
op->start([callback = std::move(callback),
|
|
641
|
+
session_manager,
|
|
642
|
+
weak_op = std::weak_ptr<pending_buffered_http_operation>{ op },
|
|
643
|
+
service = op->request().service](auto resp, auto ec) mutable {
|
|
644
|
+
callback(std::move(resp), ec);
|
|
645
|
+
if (auto self = weak_op.lock(); self) {
|
|
646
|
+
session_manager->check_in(service, self->session());
|
|
647
|
+
}
|
|
648
|
+
});
|
|
569
649
|
|
|
570
650
|
if (!session->is_connected()) {
|
|
571
651
|
session_manager->connect_then_send_pending_op(
|
|
572
652
|
session,
|
|
573
653
|
{},
|
|
574
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
575
|
-
op->dispatch_deadline_expiry(),
|
|
576
|
-
#endif
|
|
577
654
|
op->deadline_expiry(),
|
|
578
655
|
[op](std::error_code ec, std::shared_ptr<io::http_session> http_session) {
|
|
579
656
|
if (ec) {
|
|
580
|
-
|
|
657
|
+
op->invoke_response_handler(ec, {});
|
|
658
|
+
return;
|
|
581
659
|
}
|
|
582
660
|
op->send_to(std::move(http_session));
|
|
583
661
|
});
|
|
@@ -586,64 +664,6 @@ private:
|
|
|
586
664
|
}
|
|
587
665
|
}
|
|
588
666
|
|
|
589
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
590
|
-
template<typename Callback, typename PendingHttpOp>
|
|
591
|
-
auto defer_command(std::shared_ptr<PendingHttpOp> pending_op,
|
|
592
|
-
const std::shared_ptr<io::http_session_manager>& session_manager,
|
|
593
|
-
Callback&& callback) -> error_union
|
|
594
|
-
{
|
|
595
|
-
if (auto last_error = session_manager->last_bootstrap_error(); last_error.has_value()) {
|
|
596
|
-
return last_error.value();
|
|
597
|
-
}
|
|
598
|
-
CB_LOG_DEBUG(
|
|
599
|
-
R"(Adding pending HTTP operation to deferred queue: service={}, client_context_id={})",
|
|
600
|
-
pending_op->request().service,
|
|
601
|
-
pending_op->request().client_context_id);
|
|
602
|
-
session_manager->add_to_deferred_queue([this,
|
|
603
|
-
callback = std::forward<Callback>(callback),
|
|
604
|
-
op = std::move(pending_op),
|
|
605
|
-
session_manager](error_union err) mutable {
|
|
606
|
-
if (!std::holds_alternative<std::monostate>(err)) {
|
|
607
|
-
// The deferred operation was cancelled - currently this can happen due to closing the
|
|
608
|
-
// cluster
|
|
609
|
-
return callback({}, err);
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
return send_http_operation(op, session_manager, std::forward<Callback>(callback));
|
|
613
|
-
});
|
|
614
|
-
return std::monostate{};
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
auto defer_command(std::shared_ptr<pending_buffered_http_operation> pending_op,
|
|
618
|
-
const std::shared_ptr<io::http_session_manager>& session_manager,
|
|
619
|
-
buffered_free_form_http_request_callback&& callback) -> error_union
|
|
620
|
-
{
|
|
621
|
-
if (auto last_error = session_manager->last_bootstrap_error(); last_error.has_value()) {
|
|
622
|
-
return last_error.value();
|
|
623
|
-
}
|
|
624
|
-
CB_LOG_DEBUG(
|
|
625
|
-
R"(Adding pending HTTP operation to deferred queue: service={}, client_context_id={})",
|
|
626
|
-
pending_op->request().service,
|
|
627
|
-
pending_op->request().client_context_id);
|
|
628
|
-
session_manager->add_to_deferred_queue([this,
|
|
629
|
-
callback = std::move(callback),
|
|
630
|
-
op = std::move(pending_op),
|
|
631
|
-
session_manager](error_union err) mutable {
|
|
632
|
-
if (!std::holds_alternative<std::monostate>(err)) {
|
|
633
|
-
auto ec = std::holds_alternative<impl::bootstrap_error>(err)
|
|
634
|
-
? std::get<impl::bootstrap_error>(err).ec
|
|
635
|
-
: std::get<std::error_code>(err);
|
|
636
|
-
// The deferred operation was cancelled - currently this can happen due to closing the
|
|
637
|
-
// cluster
|
|
638
|
-
return callback({}, ec);
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
return send_http_operation(op, session_manager, std::move(callback));
|
|
642
|
-
});
|
|
643
|
-
return std::monostate{};
|
|
644
|
-
}
|
|
645
|
-
#endif
|
|
646
|
-
|
|
647
667
|
asio::io_context& io_;
|
|
648
668
|
core_sdk_shim shim_;
|
|
649
669
|
std::shared_ptr<retry_strategy> default_retry_strategy_;
|
|
@@ -661,11 +681,7 @@ http_component::http_component(asio::io_context& io,
|
|
|
661
681
|
auto
|
|
662
682
|
http_component::do_http_request(const http_request& request,
|
|
663
683
|
free_form_http_request_callback&& callback)
|
|
664
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
665
|
-
-> tl::expected<std::shared_ptr<pending_operation>, error_union>
|
|
666
|
-
#else
|
|
667
684
|
-> tl::expected<std::shared_ptr<pending_operation>, std::error_code>
|
|
668
|
-
#endif
|
|
669
685
|
{
|
|
670
686
|
return impl_->do_http_request(request, std::move(callback));
|
|
671
687
|
}
|