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,14 +19,16 @@
|
|
|
19
19
|
|
|
20
20
|
#include <couchbase/build_config.hxx>
|
|
21
21
|
|
|
22
|
-
#
|
|
23
|
-
#include "
|
|
24
|
-
|
|
22
|
+
#include "configuration_belongs_to_session.hxx"
|
|
23
|
+
#include "opaque_ring_table.hxx"
|
|
24
|
+
|
|
25
|
+
#include "core/app_telemetry_meter.hxx"
|
|
25
26
|
#include "core/config_listener.hxx"
|
|
26
27
|
#include "core/diagnostics.hxx"
|
|
27
28
|
#include "core/impl/bootstrap_error.hxx"
|
|
28
29
|
#include "core/impl/bootstrap_state_listener.hxx"
|
|
29
30
|
#include "core/logger/logger.hxx"
|
|
31
|
+
#include "core/logger/redaction.hxx"
|
|
30
32
|
#include "core/mcbp/codec.hxx"
|
|
31
33
|
#include "core/mcbp/queue_request.hxx"
|
|
32
34
|
#include "core/meta/version.hxx"
|
|
@@ -50,8 +52,10 @@
|
|
|
50
52
|
#include "core/sasl/error_fmt.h"
|
|
51
53
|
#include "core/topology/capabilities_fmt.hxx"
|
|
52
54
|
#include "core/topology/configuration_fmt.hxx"
|
|
55
|
+
#include "mcbp_buffer_pool.hxx"
|
|
53
56
|
#include "mcbp_context.hxx"
|
|
54
57
|
#include "mcbp_message.hxx"
|
|
58
|
+
#include "mcbp_output_queue.hxx"
|
|
55
59
|
#include "mcbp_parser.hxx"
|
|
56
60
|
#include "retry_orchestrator.hxx"
|
|
57
61
|
#include "streams.hxx"
|
|
@@ -109,7 +113,7 @@ struct mcbp_header_layout {
|
|
|
109
113
|
if (magic == 0x18 || magic == 0x08) {
|
|
110
114
|
return keylen.alt.key;
|
|
111
115
|
}
|
|
112
|
-
return couchbase::core::utils::
|
|
116
|
+
return couchbase::core::utils::network_to_host(keylen.normal);
|
|
113
117
|
}
|
|
114
118
|
|
|
115
119
|
[[nodiscard]] constexpr auto framing_extras_length() const -> std::uint8_t
|
|
@@ -149,10 +153,10 @@ struct fmt::formatter<mcbp_header_view<Container>> {
|
|
|
149
153
|
header->extlen,
|
|
150
154
|
header->datatype,
|
|
151
155
|
header->specific_name(),
|
|
152
|
-
couchbase::core::utils::
|
|
153
|
-
couchbase::core::utils::
|
|
154
|
-
couchbase::core::utils::
|
|
155
|
-
couchbase::core::utils::
|
|
156
|
+
couchbase::core::utils::network_to_host(header->specific),
|
|
157
|
+
couchbase::core::utils::network_to_host(header->bodylen),
|
|
158
|
+
couchbase::core::utils::network_to_host(header->opaque),
|
|
159
|
+
couchbase::core::utils::network_to_host(header->cas));
|
|
156
160
|
}
|
|
157
161
|
};
|
|
158
162
|
|
|
@@ -269,13 +273,21 @@ class mcbp_session_impl
|
|
|
269
273
|
hello_req.body().enable_mutation_tokens();
|
|
270
274
|
}
|
|
271
275
|
hello_req.opaque(session_->next_opaque());
|
|
272
|
-
auto
|
|
273
|
-
|
|
276
|
+
const auto& user_agent_extra = session_->origin_.options().user_agent_extra;
|
|
277
|
+
auto user_agent =
|
|
278
|
+
meta::user_agent_for_mcbp(session_->client_id_, session_->id_, user_agent_extra, 250);
|
|
274
279
|
hello_req.body().user_agent(user_agent);
|
|
275
|
-
CB_LOG_DEBUG(
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
280
|
+
CB_LOG_DEBUG(
|
|
281
|
+
"{} user_agent={}, requested_features=[{}]",
|
|
282
|
+
session_->log_prefix_,
|
|
283
|
+
// The blob folds in the application's user_agent_extra, and that is the only user data it
|
|
284
|
+
// can hold: the rest is SDK, platform and TLS identity, and its "i" field is the client
|
|
285
|
+
// and session id that log_prefix_ already prints in the clear on this same line. So it is
|
|
286
|
+
// tagged only when there is an extra to protect, which keeps the version block readable in
|
|
287
|
+
// the logs support actually receives.
|
|
288
|
+
logger::user_data_if(!user_agent_extra.empty(), user_agent),
|
|
289
|
+
// protocol feature names, not a document body
|
|
290
|
+
logger::not_sensitive(utils::join_strings_fmt(hello_req.body().features(), ", ")));
|
|
279
291
|
session_->write(hello_req.data());
|
|
280
292
|
|
|
281
293
|
if (!session_->origin_.credentials().uses_certificate()) {
|
|
@@ -370,7 +382,10 @@ class mcbp_session_impl
|
|
|
370
382
|
case protocol::client_opcode::hello: {
|
|
371
383
|
protocol::client_response<protocol::hello_response_body> resp(std::move(msg));
|
|
372
384
|
if (resp.status() == key_value_status_code::success) {
|
|
373
|
-
|
|
385
|
+
{
|
|
386
|
+
const std::scoped_lock lock(session_->session_info_mutex_);
|
|
387
|
+
session_->supported_features_ = resp.body().supported_features();
|
|
388
|
+
}
|
|
374
389
|
CB_LOG_DEBUG("{} supported_features=[{}]",
|
|
375
390
|
session_->log_prefix_,
|
|
376
391
|
utils::join_strings_fmt(session_->supported_features_, ", "));
|
|
@@ -495,7 +510,7 @@ class mcbp_session_impl
|
|
|
495
510
|
if (resp.status() == key_value_status_code::success) {
|
|
496
511
|
CB_LOG_DEBUG("{} selected bucket: {}",
|
|
497
512
|
session_->log_prefix_,
|
|
498
|
-
session_->bucket_name_.value_or(""));
|
|
513
|
+
logger::metadata(session_->bucket_name_.value_or("")));
|
|
499
514
|
session_->bucket_selected_ = true;
|
|
500
515
|
} else if (resp.status() == key_value_status_code::not_found) {
|
|
501
516
|
auto error_msg =
|
|
@@ -543,12 +558,14 @@ class mcbp_session_impl
|
|
|
543
558
|
if (session_->origin_.options().dump_configuration) {
|
|
544
559
|
if (const auto& text = resp.body().config_text(); text.has_value()) {
|
|
545
560
|
CB_LOG_TRACE("{} configuration from get_cluster_config request (bootstrap, "
|
|
546
|
-
"size={}, endpoint=\"{}
|
|
561
|
+
"size={}, endpoint=\"{}\"), {}",
|
|
547
562
|
session_->log_prefix_,
|
|
548
563
|
text.value().size(),
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
564
|
+
logger::system_data(
|
|
565
|
+
fmt::format("{}:{}", info.endpoint_address, info.endpoint_port)),
|
|
566
|
+
// an opt-in dump, it exists to show the exact bytes. That is the
|
|
567
|
+
// "none at all" case of the rule in redaction.hxx.
|
|
568
|
+
logger::not_redacted(text.value()));
|
|
552
569
|
}
|
|
553
570
|
}
|
|
554
571
|
if (resp.status() == key_value_status_code::success) {
|
|
@@ -625,44 +642,42 @@ class mcbp_session_impl
|
|
|
625
642
|
if (session_->origin_.options().dump_configuration) {
|
|
626
643
|
if (const auto& text = req.body().config_text(); text.has_value()) {
|
|
627
644
|
CB_LOG_TRACE("{} configuration from cluster_map_change_notification request "
|
|
628
|
-
"(size={}, endpoint=\"{}
|
|
645
|
+
"(size={}, endpoint=\"{}\"), {}",
|
|
629
646
|
session_->log_prefix_,
|
|
630
647
|
text.value().size(),
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
648
|
+
logger::system_data(
|
|
649
|
+
fmt::format("{}:{}", info.endpoint_address, info.endpoint_port)),
|
|
650
|
+
// an opt-in dump, it exists to show the exact bytes. That is the
|
|
651
|
+
// "none at all" case of the rule in redaction.hxx.
|
|
652
|
+
logger::not_redacted(text.value()));
|
|
634
653
|
}
|
|
635
654
|
}
|
|
636
655
|
std::optional<topology::configuration> config = req.body().config();
|
|
637
|
-
if (session_ && config.has_value()
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
// TODO(CXXCBC-549)
|
|
641
|
-
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
|
642
|
-
session_->bucket_name_.value() == req.body().bucket())) {
|
|
643
|
-
session_->update_configuration(std::move(config.value()));
|
|
644
|
-
}
|
|
656
|
+
if (session_ && config.has_value() &&
|
|
657
|
+
configuration_belongs_to_session(config->bucket, session_->bucket_name_)) {
|
|
658
|
+
session_->update_configuration(std::move(config.value()));
|
|
645
659
|
}
|
|
646
660
|
} break;
|
|
647
661
|
default:
|
|
648
|
-
CB_LOG_WARNING("{} unexpected server request: opcode={:x}, opaque={}{:a}
|
|
662
|
+
CB_LOG_WARNING("{} unexpected server request: opcode={:x}, opaque={}{:a}",
|
|
649
663
|
session_->log_prefix_,
|
|
650
664
|
msg.header.opcode,
|
|
651
|
-
utils::
|
|
652
|
-
|
|
653
|
-
spdlog::to_hex(msg.
|
|
665
|
+
utils::network_to_host(msg.header.opaque),
|
|
666
|
+
// No need to dump the body here, CB_LOG_PROTOCOL has the raw bytes.
|
|
667
|
+
spdlog::to_hex(msg.header_data()));
|
|
654
668
|
}
|
|
655
669
|
break;
|
|
656
670
|
case protocol::magic::client_request:
|
|
657
671
|
case protocol::magic::alt_client_request:
|
|
658
672
|
case protocol::magic::server_response:
|
|
659
|
-
|
|
673
|
+
case protocol::magic::invalid:
|
|
674
|
+
CB_LOG_WARNING("{} unexpected magic: {} (opcode={:x}, opaque={}){:a}",
|
|
660
675
|
session_->log_prefix_,
|
|
661
676
|
magic,
|
|
662
677
|
msg.header.opcode,
|
|
663
|
-
utils::
|
|
664
|
-
|
|
665
|
-
spdlog::to_hex(msg.
|
|
678
|
+
utils::network_to_host(msg.header.opaque),
|
|
679
|
+
// No need to dump the body here, CB_LOG_PROTOCOL has the raw bytes.
|
|
680
|
+
spdlog::to_hex(msg.header_data()));
|
|
666
681
|
break;
|
|
667
682
|
}
|
|
668
683
|
}
|
|
@@ -717,12 +732,14 @@ class mcbp_session_impl
|
|
|
717
732
|
if (session_->origin_.options().dump_configuration) {
|
|
718
733
|
if (const auto& text = resp.body().config_text(); text.has_value()) {
|
|
719
734
|
CB_LOG_TRACE("{} configuration from get_cluster_config response (size={}, "
|
|
720
|
-
"endpoint=\"{}
|
|
735
|
+
"endpoint=\"{}\"), {}",
|
|
721
736
|
session_->log_prefix_,
|
|
722
737
|
text.value().size(),
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
738
|
+
logger::system_data(
|
|
739
|
+
fmt::format("{}:{}", info.endpoint_address, info.endpoint_port)),
|
|
740
|
+
// an opt-in dump, it exists to show the exact bytes. That is the
|
|
741
|
+
// "none at all" case of the rule in redaction.hxx.
|
|
742
|
+
logger::not_redacted(text.value()));
|
|
726
743
|
}
|
|
727
744
|
}
|
|
728
745
|
if (resp.status() == key_value_status_code::success) {
|
|
@@ -767,7 +784,7 @@ class mcbp_session_impl
|
|
|
767
784
|
case protocol::client_opcode::subdoc_multi_lookup:
|
|
768
785
|
case protocol::client_opcode::subdoc_multi_mutation:
|
|
769
786
|
case protocol::client_opcode::sasl_auth: {
|
|
770
|
-
const std::uint16_t status = utils::
|
|
787
|
+
const std::uint16_t status = utils::network_to_host(msg.header.specific);
|
|
771
788
|
if (status == static_cast<std::uint16_t>(key_value_status_code::not_my_vbucket)) {
|
|
772
789
|
session_->handle_not_my_vbucket(msg);
|
|
773
790
|
}
|
|
@@ -775,12 +792,12 @@ class mcbp_session_impl
|
|
|
775
792
|
CB_LOG_WARNING("{} received auth stale status for {}, opaque={}",
|
|
776
793
|
session_->log_prefix_,
|
|
777
794
|
protocol::client_opcode(msg.header.opcode),
|
|
778
|
-
utils::
|
|
795
|
+
utils::network_to_host(msg.header.opaque));
|
|
779
796
|
session_->stop(retry_reason::do_not_retry);
|
|
780
797
|
return;
|
|
781
798
|
}
|
|
782
799
|
|
|
783
|
-
std::uint32_t opaque = utils::
|
|
800
|
+
std::uint32_t opaque = utils::network_to_host(msg.header.opaque);
|
|
784
801
|
if (session_->handle_request(opcode, status, opaque, std::move(msg))) {
|
|
785
802
|
CB_LOG_TRACE("{} MCBP invoked operation handler: opcode={}, opaque={}, status={}",
|
|
786
803
|
session_->log_prefix_,
|
|
@@ -796,12 +813,12 @@ class mcbp_session_impl
|
|
|
796
813
|
}
|
|
797
814
|
} break;
|
|
798
815
|
default:
|
|
799
|
-
CB_LOG_WARNING("{} unexpected client response: opcode={}, opaque={}{:a}
|
|
816
|
+
CB_LOG_WARNING("{} unexpected client response: opcode={}, opaque={}{:a})",
|
|
800
817
|
session_->log_prefix_,
|
|
801
818
|
opcode,
|
|
802
819
|
msg.header.opaque,
|
|
803
|
-
|
|
804
|
-
spdlog::to_hex(msg.
|
|
820
|
+
// No need to dump the body here, CB_LOG_PROTOCOL has the raw bytes.
|
|
821
|
+
spdlog::to_hex(msg.header_data()));
|
|
805
822
|
}
|
|
806
823
|
break;
|
|
807
824
|
case protocol::magic::server_request:
|
|
@@ -815,44 +832,42 @@ class mcbp_session_impl
|
|
|
815
832
|
if (session_->origin_.options().dump_configuration) {
|
|
816
833
|
if (const auto& text = req.body().config_text(); text.has_value()) {
|
|
817
834
|
CB_LOG_TRACE("{} configuration from cluster_map_change_notification request "
|
|
818
|
-
"(size={}, endpoint=\"{}
|
|
835
|
+
"(size={}, endpoint=\"{}\"), {}",
|
|
819
836
|
session_->log_prefix_,
|
|
820
837
|
text.value().size(),
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
838
|
+
logger::system_data(
|
|
839
|
+
fmt::format("{}:{}", info.endpoint_address, info.endpoint_port)),
|
|
840
|
+
// an opt-in dump, it exists to show the exact bytes. That is the
|
|
841
|
+
// "none at all" case of the rule in redaction.hxx.
|
|
842
|
+
logger::not_redacted(text.value()));
|
|
824
843
|
}
|
|
825
844
|
}
|
|
826
845
|
std::optional<topology::configuration> config = req.body().config();
|
|
827
|
-
if (session_ && config.has_value()
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
// TODO(CXXCBC-549)
|
|
831
|
-
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
|
832
|
-
session_->bucket_name_.value() == req.body().bucket())) {
|
|
833
|
-
session_->update_configuration(std::move(config.value()));
|
|
834
|
-
}
|
|
846
|
+
if (session_ && config.has_value() &&
|
|
847
|
+
configuration_belongs_to_session(config->bucket, session_->bucket_name_)) {
|
|
848
|
+
session_->update_configuration(std::move(config.value()));
|
|
835
849
|
}
|
|
836
850
|
} break;
|
|
837
851
|
default:
|
|
838
|
-
CB_LOG_WARNING("{} unexpected server request: opcode={:x}, opaque={}{:a}
|
|
852
|
+
CB_LOG_WARNING("{} unexpected server request: opcode={:x}, opaque={}{:a}",
|
|
839
853
|
session_->log_prefix_,
|
|
840
854
|
msg.header.opcode,
|
|
841
855
|
msg.header.opaque,
|
|
842
|
-
|
|
843
|
-
spdlog::to_hex(msg.
|
|
856
|
+
// No need to dump the body here, CB_LOG_PROTOCOL has the raw bytes.
|
|
857
|
+
spdlog::to_hex(msg.header_data()));
|
|
844
858
|
}
|
|
845
859
|
break;
|
|
846
860
|
case protocol::magic::client_request:
|
|
847
861
|
case protocol::magic::alt_client_request:
|
|
848
862
|
case protocol::magic::server_response:
|
|
849
|
-
|
|
863
|
+
case protocol::magic::invalid:
|
|
864
|
+
CB_LOG_WARNING("{} unexpected magic: {} (opcode={:x}, opaque={}){:a}",
|
|
850
865
|
session_->log_prefix_,
|
|
851
866
|
magic,
|
|
852
867
|
msg.header.opcode,
|
|
853
868
|
msg.header.opaque,
|
|
854
|
-
|
|
855
|
-
spdlog::to_hex(msg.
|
|
869
|
+
// No need to dump the body here, CB_LOG_PROTOCOL has the raw bytes.
|
|
870
|
+
spdlog::to_hex(msg.header_data()));
|
|
856
871
|
break;
|
|
857
872
|
}
|
|
858
873
|
}
|
|
@@ -886,7 +901,7 @@ public:
|
|
|
886
901
|
, codec_{ { supported_features_.begin(), supported_features_.end() } }
|
|
887
902
|
{
|
|
888
903
|
log_prefix_ = fmt::format(
|
|
889
|
-
"[{}/{}/{}/{}]", client_id_, id_, stream_->log_prefix(),
|
|
904
|
+
"[{}/{}/{}/{}]", client_id_, id_, stream_->log_prefix(), log_prefix_bucket_name());
|
|
890
905
|
}
|
|
891
906
|
|
|
892
907
|
mcbp_session_impl(std::string_view client_id,
|
|
@@ -916,7 +931,7 @@ public:
|
|
|
916
931
|
, codec_{ { supported_features_.begin(), supported_features_.end() } }
|
|
917
932
|
{
|
|
918
933
|
log_prefix_ = fmt::format(
|
|
919
|
-
"[{}/{}/{}/{}]", client_id_, id_, stream_->log_prefix(),
|
|
934
|
+
"[{}/{}/{}/{}]", client_id_, id_, stream_->log_prefix(), log_prefix_bucket_name());
|
|
920
935
|
}
|
|
921
936
|
|
|
922
937
|
mcbp_session_impl(const mcbp_session_impl&) = delete;
|
|
@@ -930,8 +945,9 @@ public:
|
|
|
930
945
|
stop(retry_reason::do_not_retry);
|
|
931
946
|
}
|
|
932
947
|
|
|
933
|
-
[[nodiscard]] auto log_prefix() const ->
|
|
948
|
+
[[nodiscard]] auto log_prefix() const -> std::string
|
|
934
949
|
{
|
|
950
|
+
const std::scoped_lock lock(session_info_mutex_);
|
|
935
951
|
return log_prefix_;
|
|
936
952
|
}
|
|
937
953
|
|
|
@@ -1063,6 +1079,7 @@ public:
|
|
|
1063
1079
|
|
|
1064
1080
|
[[nodiscard]] auto context() const -> mcbp_context
|
|
1065
1081
|
{
|
|
1082
|
+
const std::scoped_lock lock(session_info_mutex_);
|
|
1066
1083
|
return { config_, supported_features_ };
|
|
1067
1084
|
}
|
|
1068
1085
|
|
|
@@ -1159,7 +1176,8 @@ public:
|
|
|
1159
1176
|
}
|
|
1160
1177
|
|
|
1161
1178
|
if (reason == retry_reason::do_not_retry || reason == retry_reason::unknown) {
|
|
1162
|
-
CB_LOG_WARNING("{} reauthentication failed (code={}, message={}, reason={}, opaque={})"
|
|
1179
|
+
CB_LOG_WARNING("{} reauthentication failed (code={}, message={}, reason={}, opaque={}), "
|
|
1180
|
+
"closing connection",
|
|
1163
1181
|
self->log_prefix_,
|
|
1164
1182
|
ec.value(),
|
|
1165
1183
|
ec.message(),
|
|
@@ -1167,6 +1185,7 @@ public:
|
|
|
1167
1185
|
req.opaque());
|
|
1168
1186
|
self->reauth_deadline_.cancel();
|
|
1169
1187
|
self->reauth_in_progress_ = false;
|
|
1188
|
+
self->stop(retry_reason::do_not_retry);
|
|
1170
1189
|
return;
|
|
1171
1190
|
}
|
|
1172
1191
|
|
|
@@ -1208,45 +1227,6 @@ public:
|
|
|
1208
1227
|
self->state_listener_->report_bootstrap_error(
|
|
1209
1228
|
fmt::format("{}:{}", self->bootstrap_hostname_, self->bootstrap_port_), ec);
|
|
1210
1229
|
}
|
|
1211
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
1212
|
-
// an existing background bootstrap listener means we want to infinitely
|
|
1213
|
-
// attempt to connect.
|
|
1214
|
-
if (self->background_bootstrap_listener_) {
|
|
1215
|
-
if (self->last_bootstrap_error_.has_value()) {
|
|
1216
|
-
self->background_bootstrap_listener_->notify_bootstrap_error(
|
|
1217
|
-
self->last_bootstrap_error_.value());
|
|
1218
|
-
} else {
|
|
1219
|
-
self->background_bootstrap_listener_->notify_bootstrap_error(
|
|
1220
|
-
{ make_error_code(errc::common::unambiguous_timeout),
|
|
1221
|
-
"Unable to connect in time.",
|
|
1222
|
-
self->bootstrap_hostname_,
|
|
1223
|
-
self->bootstrap_port_ });
|
|
1224
|
-
}
|
|
1225
|
-
auto backoff = std::chrono::milliseconds(500);
|
|
1226
|
-
CB_LOG_DEBUG("{} unable to connect in time, waiting for {}ms before retry",
|
|
1227
|
-
self->log_prefix_,
|
|
1228
|
-
backoff.count());
|
|
1229
|
-
self->retry_backoff_.expires_after(backoff);
|
|
1230
|
-
self->retry_backoff_.async_wait([self](std::error_code ec) mutable {
|
|
1231
|
-
if (ec == asio::error::operation_aborted || self->stopped_) {
|
|
1232
|
-
return;
|
|
1233
|
-
}
|
|
1234
|
-
self->origin_.restart();
|
|
1235
|
-
self->initiate_bootstrap();
|
|
1236
|
-
});
|
|
1237
|
-
} else {
|
|
1238
|
-
if (!ec) {
|
|
1239
|
-
ec = errc::common::unambiguous_timeout;
|
|
1240
|
-
}
|
|
1241
|
-
CB_LOG_WARNING("{} unable to bootstrap in time, bootstrap_timeout: {}",
|
|
1242
|
-
self->log_prefix_,
|
|
1243
|
-
bootstrap_timeout);
|
|
1244
|
-
if (auto h = std::move(self->bootstrap_callback_); h) {
|
|
1245
|
-
h(ec, {});
|
|
1246
|
-
}
|
|
1247
|
-
self->stop(retry_reason::do_not_retry);
|
|
1248
|
-
}
|
|
1249
|
-
#else
|
|
1250
1230
|
if (!ec) {
|
|
1251
1231
|
ec = errc::common::unambiguous_timeout;
|
|
1252
1232
|
}
|
|
@@ -1257,7 +1237,6 @@ public:
|
|
|
1257
1237
|
h(ec, {});
|
|
1258
1238
|
}
|
|
1259
1239
|
self->stop(retry_reason::do_not_retry);
|
|
1260
|
-
#endif
|
|
1261
1240
|
});
|
|
1262
1241
|
initiate_bootstrap();
|
|
1263
1242
|
}
|
|
@@ -1278,25 +1257,12 @@ public:
|
|
|
1278
1257
|
self->log_prefix_,
|
|
1279
1258
|
old_id,
|
|
1280
1259
|
self->stream_->id(),
|
|
1281
|
-
self->bootstrap_hostname_,
|
|
1282
|
-
self->bootstrap_port_);
|
|
1260
|
+
logger::system_data(self->bootstrap_hostname_),
|
|
1261
|
+
logger::system_data(self->bootstrap_port_));
|
|
1283
1262
|
return self->initiate_bootstrap();
|
|
1284
1263
|
});
|
|
1285
1264
|
}
|
|
1286
1265
|
if (origin_.exhausted()) {
|
|
1287
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
1288
|
-
if (background_bootstrap_listener_) {
|
|
1289
|
-
if (last_bootstrap_error_.has_value()) {
|
|
1290
|
-
background_bootstrap_listener_->notify_bootstrap_error(last_bootstrap_error_.value());
|
|
1291
|
-
} else {
|
|
1292
|
-
background_bootstrap_listener_->notify_bootstrap_error(
|
|
1293
|
-
{ errc::network::no_endpoints_left,
|
|
1294
|
-
"Reached end of list of bootstrap nodes.",
|
|
1295
|
-
bootstrap_hostname_,
|
|
1296
|
-
bootstrap_port_ });
|
|
1297
|
-
}
|
|
1298
|
-
}
|
|
1299
|
-
#endif
|
|
1300
1266
|
auto backoff = std::chrono::milliseconds(500);
|
|
1301
1267
|
CB_LOG_DEBUG("{} reached the end of list of bootstrap nodes, waiting for {}ms before restart",
|
|
1302
1268
|
log_prefix_,
|
|
@@ -1315,12 +1281,15 @@ public:
|
|
|
1315
1281
|
bootstrap_port_number_ =
|
|
1316
1282
|
gsl::narrow_cast<std::uint16_t>(std::stoul(bootstrap_port_, nullptr, 10));
|
|
1317
1283
|
bootstrap_address_ = fmt::format("{}:{}", bootstrap_hostname_, bootstrap_port_);
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1284
|
+
{
|
|
1285
|
+
const std::scoped_lock lock(session_info_mutex_);
|
|
1286
|
+
log_prefix_ = fmt::format("[{}/{}/{}/{}] <{}>",
|
|
1287
|
+
client_id_,
|
|
1288
|
+
id_,
|
|
1289
|
+
stream_->log_prefix(),
|
|
1290
|
+
log_prefix_bucket_name(),
|
|
1291
|
+
logger::system_data(bootstrap_address_));
|
|
1292
|
+
}
|
|
1324
1293
|
CB_LOG_DEBUG("{} attempt to establish MCBP connection", log_prefix_);
|
|
1325
1294
|
|
|
1326
1295
|
resolve_deadline_.expires_after(origin_.options().resolve_timeout);
|
|
@@ -1349,6 +1318,12 @@ public:
|
|
|
1349
1318
|
return node_uuid_;
|
|
1350
1319
|
}
|
|
1351
1320
|
|
|
1321
|
+
auto app_telemetry_recorder(app_telemetry_meter& meter, const std::string& bucket_name)
|
|
1322
|
+
-> std::shared_ptr<app_telemetry_value_recorder>
|
|
1323
|
+
{
|
|
1324
|
+
return app_telemetry_recorder_cache_.value_recorder(meter, node_uuid_, bucket_name);
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1352
1327
|
[[nodiscard]] auto is_stopped() const -> bool
|
|
1353
1328
|
{
|
|
1354
1329
|
return stopped_;
|
|
@@ -1371,33 +1346,48 @@ public:
|
|
|
1371
1346
|
}
|
|
1372
1347
|
|
|
1373
1348
|
if (reason == retry_reason::socket_closed_while_in_flight && !bootstrapped_) {
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
self->stream_->
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1349
|
+
// Dispatch close through the stream's strand to serialize with any in-flight on_connect
|
|
1350
|
+
// that may be reading plain_stream_impl::stream_ concurrently.
|
|
1351
|
+
return asio::dispatch(
|
|
1352
|
+
stream_->get_executor(),
|
|
1353
|
+
[self = shared_from_this(), old_id = stream_->id()]() mutable -> void {
|
|
1354
|
+
self->stream_->close([self, old_id = std::move(old_id)](std::error_code) mutable -> void {
|
|
1355
|
+
CB_LOG_DEBUG(
|
|
1356
|
+
R"({} reopened socket connection due to IO error, "{}" -> "{}", host="{}", port={})",
|
|
1357
|
+
self->log_prefix_,
|
|
1358
|
+
old_id,
|
|
1359
|
+
self->stream_->id(),
|
|
1360
|
+
logger::system_data(self->bootstrap_hostname_),
|
|
1361
|
+
logger::system_data(self->bootstrap_port_));
|
|
1362
|
+
return self->initiate_bootstrap();
|
|
1363
|
+
});
|
|
1364
|
+
});
|
|
1384
1365
|
}
|
|
1385
1366
|
|
|
1386
1367
|
state_ = diag::endpoint_state::disconnecting;
|
|
1387
|
-
|
|
1368
|
+
std::string stop_log_prefix;
|
|
1369
|
+
{
|
|
1370
|
+
const std::scoped_lock lock(session_info_mutex_);
|
|
1371
|
+
stop_log_prefix = log_prefix_;
|
|
1372
|
+
}
|
|
1373
|
+
CB_LOG_DEBUG("{} stop MCBP connection, reason={}", stop_log_prefix, reason);
|
|
1388
1374
|
stopped_ = true;
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1375
|
+
// Dispatch timer cancellation and stream close through the strand to avoid
|
|
1376
|
+
// racing with on_connect() and bootstrap_handler which run on the IO thread.
|
|
1377
|
+
asio::dispatch(stream_->get_executor(), [self = shared_from_this()]() -> void {
|
|
1378
|
+
self->bootstrap_deadline_.cancel();
|
|
1379
|
+
self->resolve_deadline_.cancel();
|
|
1380
|
+
self->connection_deadline_.cancel();
|
|
1381
|
+
self->reauth_deadline_.cancel();
|
|
1382
|
+
self->retry_backoff_.cancel();
|
|
1383
|
+
self->ping_timeout_.cancel();
|
|
1384
|
+
self->resolver_.cancel();
|
|
1385
|
+
if (auto h = std::move(self->bootstrap_handler_); h) {
|
|
1386
|
+
h->stop();
|
|
1387
|
+
}
|
|
1388
|
+
self->stream_->close([](std::error_code) -> void {
|
|
1389
|
+
});
|
|
1397
1390
|
});
|
|
1398
|
-
if (auto h = std::move(bootstrap_handler_); h) {
|
|
1399
|
-
h->stop();
|
|
1400
|
-
}
|
|
1401
1391
|
if (auto h = std::move(handler_); h) {
|
|
1402
1392
|
h->stop();
|
|
1403
1393
|
}
|
|
@@ -1408,18 +1398,23 @@ public:
|
|
|
1408
1398
|
}
|
|
1409
1399
|
}
|
|
1410
1400
|
{
|
|
1411
|
-
|
|
1412
|
-
|
|
1401
|
+
// Drain under the lock, then invoke the handlers after releasing it: a command handler may
|
|
1402
|
+
// re-enter the session (as cancel() documents), so running one while holding
|
|
1403
|
+
// command_handlers_mutex_ could deadlock during shutdown.
|
|
1404
|
+
auto cancelled = [this] {
|
|
1405
|
+
const std::scoped_lock lock(command_handlers_mutex_);
|
|
1406
|
+
return command_handlers_.drain();
|
|
1407
|
+
}();
|
|
1408
|
+
for (auto& [opaque, handler] : cancelled) {
|
|
1413
1409
|
if (handler) {
|
|
1414
1410
|
CB_LOG_DEBUG("{} MCBP cancel operation during session close, opaque={}, ec={}",
|
|
1415
|
-
|
|
1411
|
+
stop_log_prefix,
|
|
1416
1412
|
opaque,
|
|
1417
1413
|
ec.message());
|
|
1418
1414
|
auto fun = std::move(handler);
|
|
1419
1415
|
fun(ec, reason, {}, {});
|
|
1420
1416
|
}
|
|
1421
1417
|
}
|
|
1422
|
-
command_handlers_.clear();
|
|
1423
1418
|
}
|
|
1424
1419
|
{
|
|
1425
1420
|
const std::scoped_lock lock(operations_mutex_);
|
|
@@ -1428,24 +1423,23 @@ public:
|
|
|
1428
1423
|
auto& [request, handler] = operation;
|
|
1429
1424
|
if (handler) {
|
|
1430
1425
|
CB_LOG_DEBUG("{} MCBP cancel operation during session close, opaque={}, ec={}",
|
|
1431
|
-
|
|
1426
|
+
stop_log_prefix,
|
|
1432
1427
|
opaque,
|
|
1433
1428
|
ec.message());
|
|
1434
|
-
handler->handle_response(
|
|
1429
|
+
handler->handle_response(
|
|
1430
|
+
std::move(request), io::mcbp_session(shared_from_this()), ec, reason, {}, {});
|
|
1435
1431
|
}
|
|
1436
1432
|
}
|
|
1437
1433
|
operations_.clear();
|
|
1438
1434
|
}
|
|
1439
|
-
|
|
1435
|
+
{
|
|
1436
|
+
const std::scoped_lock lock(session_info_mutex_);
|
|
1437
|
+
config_listeners_.clear();
|
|
1438
|
+
}
|
|
1440
1439
|
state_ = diag::endpoint_state::disconnected;
|
|
1441
1440
|
if (auto on_stop = std::move(on_stop_handler_); on_stop) {
|
|
1442
1441
|
on_stop();
|
|
1443
1442
|
}
|
|
1444
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
1445
|
-
if (background_bootstrap_listener_) {
|
|
1446
|
-
background_bootstrap_listener_ = nullptr;
|
|
1447
|
-
}
|
|
1448
|
-
#endif
|
|
1449
1443
|
}
|
|
1450
1444
|
|
|
1451
1445
|
void write(std::vector<std::byte>&& buf)
|
|
@@ -1454,8 +1448,7 @@ public:
|
|
|
1454
1448
|
return;
|
|
1455
1449
|
}
|
|
1456
1450
|
CB_LOG_TRACE("{} MCBP send {}", log_prefix_, mcbp_header_view(buf));
|
|
1457
|
-
|
|
1458
|
-
output_buffer_.emplace_back(std::move(buf));
|
|
1451
|
+
output_queue_.stage(std::move(buf));
|
|
1459
1452
|
}
|
|
1460
1453
|
|
|
1461
1454
|
void flush()
|
|
@@ -1463,9 +1456,13 @@ public:
|
|
|
1463
1456
|
if (stopped_) {
|
|
1464
1457
|
return;
|
|
1465
1458
|
}
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1459
|
+
// Only post when the queue was idle; while a write is scheduled or in flight the completion
|
|
1460
|
+
// handler re-drives do_write, so an extra post would be wasted work on the hot path.
|
|
1461
|
+
if (output_queue_.mark_for_dispatch()) {
|
|
1462
|
+
asio::post(asio::bind_executor(ctx_, [self = shared_from_this()]() {
|
|
1463
|
+
self->do_write();
|
|
1464
|
+
}));
|
|
1465
|
+
}
|
|
1469
1466
|
}
|
|
1470
1467
|
|
|
1471
1468
|
void write_and_flush(std::vector<std::byte>&& buf)
|
|
@@ -1473,8 +1470,13 @@ public:
|
|
|
1473
1470
|
if (stopped_) {
|
|
1474
1471
|
return;
|
|
1475
1472
|
}
|
|
1476
|
-
|
|
1477
|
-
|
|
1473
|
+
CB_LOG_TRACE("{} MCBP send {}", log_prefix_, mcbp_header_view(buf));
|
|
1474
|
+
// Stage the buffer and post do_write only on the idle -> scheduled transition (single lock).
|
|
1475
|
+
if (output_queue_.enqueue(std::move(buf))) {
|
|
1476
|
+
asio::post(asio::bind_executor(ctx_, [self = shared_from_this()]() {
|
|
1477
|
+
self->do_write();
|
|
1478
|
+
}));
|
|
1479
|
+
}
|
|
1478
1480
|
}
|
|
1479
1481
|
|
|
1480
1482
|
void remove_request(std::shared_ptr<mcbp::queue_request> request) override
|
|
@@ -1503,11 +1505,7 @@ public:
|
|
|
1503
1505
|
command_handler fun{};
|
|
1504
1506
|
{
|
|
1505
1507
|
const std::scoped_lock lock(command_handlers_mutex_);
|
|
1506
|
-
|
|
1507
|
-
handler != command_handlers_.end() && handler->second) {
|
|
1508
|
-
fun = std::move(handler->second);
|
|
1509
|
-
command_handlers_.erase(handler);
|
|
1510
|
-
}
|
|
1508
|
+
fun = command_handlers_.take(opaque);
|
|
1511
1509
|
}
|
|
1512
1510
|
|
|
1513
1511
|
auto reason = status == static_cast<std::uint16_t>(key_value_status_code::not_my_vbucket)
|
|
@@ -1536,6 +1534,7 @@ public:
|
|
|
1536
1534
|
}
|
|
1537
1535
|
if (request) {
|
|
1538
1536
|
handler->handle_response(std::move(request),
|
|
1537
|
+
io::mcbp_session(shared_from_this()),
|
|
1539
1538
|
protocol::map_status_code(opcode, status),
|
|
1540
1539
|
reason,
|
|
1541
1540
|
std::move(msg),
|
|
@@ -1560,6 +1559,7 @@ public:
|
|
|
1560
1559
|
CB_LOG_WARNING("cancel operation while trying to write to closed mcbp session, opaque={}",
|
|
1561
1560
|
opaque);
|
|
1562
1561
|
handler->handle_response(request,
|
|
1562
|
+
io::mcbp_session(shared_from_this()),
|
|
1563
1563
|
errc::common::request_canceled,
|
|
1564
1564
|
retry_reason::socket_closed_while_in_flight,
|
|
1565
1565
|
{},
|
|
@@ -1595,7 +1595,7 @@ public:
|
|
|
1595
1595
|
}
|
|
1596
1596
|
{
|
|
1597
1597
|
const std::scoped_lock lock(command_handlers_mutex_);
|
|
1598
|
-
command_handlers_.
|
|
1598
|
+
command_handlers_.insert(opaque, std::move(handler));
|
|
1599
1599
|
}
|
|
1600
1600
|
if (bootstrapped_ && stream_->is_open()) {
|
|
1601
1601
|
write_and_flush(std::move(data));
|
|
@@ -1617,33 +1617,34 @@ public:
|
|
|
1617
1617
|
if (stopped_) {
|
|
1618
1618
|
return false;
|
|
1619
1619
|
}
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
opaque,
|
|
1625
|
-
ec.value(),
|
|
1626
|
-
ec.message());
|
|
1627
|
-
if (handler->second) {
|
|
1628
|
-
auto fun = std::move(handler->second);
|
|
1629
|
-
command_handlers_.erase(handler);
|
|
1630
|
-
command_handlers_mutex_.unlock();
|
|
1631
|
-
fun(ec, reason, {}, {});
|
|
1632
|
-
return true;
|
|
1633
|
-
}
|
|
1620
|
+
std::unique_lock lock(command_handlers_mutex_);
|
|
1621
|
+
auto fun = command_handlers_.take(opaque);
|
|
1622
|
+
if (!fun) {
|
|
1623
|
+
return false;
|
|
1634
1624
|
}
|
|
1635
|
-
|
|
1636
|
-
|
|
1625
|
+
CB_LOG_DEBUG("{} MCBP cancel operation, opaque={}, ec={} ({})",
|
|
1626
|
+
log_prefix_,
|
|
1627
|
+
opaque,
|
|
1628
|
+
ec.value(),
|
|
1629
|
+
ec.message());
|
|
1630
|
+
// Release before invoking the handler: it must not run while holding the command-handlers
|
|
1631
|
+
// lock (it may re-enter the session), and the unique_lock guarantees the mutex is freed on
|
|
1632
|
+
// every path -- including an early return or an exception before this point.
|
|
1633
|
+
lock.unlock();
|
|
1634
|
+
fun(ec, reason, {}, {});
|
|
1635
|
+
return true;
|
|
1637
1636
|
}
|
|
1638
1637
|
|
|
1639
1638
|
[[nodiscard]] auto supports_feature(protocol::hello_feature feature) -> bool
|
|
1640
1639
|
{
|
|
1640
|
+
const std::scoped_lock lock(session_info_mutex_);
|
|
1641
1641
|
return std::find(supported_features_.begin(), supported_features_.end(), feature) !=
|
|
1642
1642
|
supported_features_.end();
|
|
1643
1643
|
}
|
|
1644
1644
|
|
|
1645
1645
|
[[nodiscard]] auto supported_features() const -> std::vector<protocol::hello_feature>
|
|
1646
1646
|
{
|
|
1647
|
+
const std::scoped_lock lock(session_info_mutex_);
|
|
1647
1648
|
return supported_features_;
|
|
1648
1649
|
}
|
|
1649
1650
|
|
|
@@ -1713,16 +1714,6 @@ public:
|
|
|
1713
1714
|
return ++opaque_;
|
|
1714
1715
|
}
|
|
1715
1716
|
|
|
1716
|
-
[[nodiscard]] auto last_bootstrap_error() && -> std::optional<impl::bootstrap_error>
|
|
1717
|
-
{
|
|
1718
|
-
return std::move(last_bootstrap_error_);
|
|
1719
|
-
}
|
|
1720
|
-
|
|
1721
|
-
[[nodiscard]] auto last_bootstrap_error() const& -> const std::optional<impl::bootstrap_error>&
|
|
1722
|
-
{
|
|
1723
|
-
return last_bootstrap_error_;
|
|
1724
|
-
}
|
|
1725
|
-
|
|
1726
1717
|
auto decode_error_code(std::uint16_t code) -> std::optional<key_value_error_map_info>
|
|
1727
1718
|
{
|
|
1728
1719
|
if (error_map_) {
|
|
@@ -1736,6 +1727,7 @@ public:
|
|
|
1736
1727
|
|
|
1737
1728
|
void on_configuration_update(std::shared_ptr<config_listener> handler)
|
|
1738
1729
|
{
|
|
1730
|
+
const std::scoped_lock lock(session_info_mutex_);
|
|
1739
1731
|
config_listeners_.emplace_back(std::move(handler));
|
|
1740
1732
|
}
|
|
1741
1733
|
|
|
@@ -1799,10 +1791,13 @@ public:
|
|
|
1799
1791
|
config_.reset();
|
|
1800
1792
|
config_.emplace(std::move(config));
|
|
1801
1793
|
configured_ = true;
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1794
|
+
{
|
|
1795
|
+
const std::scoped_lock listeners_lock(session_info_mutex_);
|
|
1796
|
+
for (const auto& listener : config_listeners_) {
|
|
1797
|
+
asio::post(asio::bind_executor(ctx_, [listener, c = config_.value()]() mutable {
|
|
1798
|
+
return listener->update_config(std::move(c));
|
|
1799
|
+
}));
|
|
1800
|
+
}
|
|
1806
1801
|
}
|
|
1807
1802
|
}
|
|
1808
1803
|
|
|
@@ -1817,25 +1812,27 @@ public:
|
|
|
1817
1812
|
auto magic = static_cast<protocol::magic>(msg.header.magic);
|
|
1818
1813
|
const std::uint8_t extras_size = msg.header.extlen;
|
|
1819
1814
|
std::uint8_t framing_extras_size = 0;
|
|
1820
|
-
std::uint16_t key_size = utils::
|
|
1815
|
+
std::uint16_t key_size = utils::network_to_host(msg.header.keylen);
|
|
1821
1816
|
if (magic == protocol::magic::alt_client_response) {
|
|
1822
|
-
|
|
1823
|
-
|
|
1817
|
+
const auto sizes = msg.header.alt_sizes();
|
|
1818
|
+
framing_extras_size = sizes.framing_extras;
|
|
1819
|
+
key_size = sizes.key;
|
|
1824
1820
|
}
|
|
1825
1821
|
|
|
1826
1822
|
const std::vector<std::uint8_t>::difference_type offset =
|
|
1827
1823
|
framing_extras_size + key_size + extras_size;
|
|
1828
|
-
if (utils::
|
|
1829
|
-
std::string_view config_text{ reinterpret_cast<const char*>(msg.body.data()) + offset,
|
|
1830
|
-
|
|
1824
|
+
if (utils::network_to_host(msg.header.bodylen) - offset > 0) {
|
|
1825
|
+
const std::string_view config_text{ reinterpret_cast<const char*>(msg.body.data()) + offset,
|
|
1826
|
+
msg.body.size() - static_cast<std::size_t>(offset) };
|
|
1831
1827
|
if (origin_.options().dump_configuration) {
|
|
1832
1828
|
CB_LOG_TRACE(
|
|
1833
|
-
"{} configuration from not_my_vbucket response (size={}, endpoint=\"{}
|
|
1829
|
+
"{} configuration from not_my_vbucket response (size={}, endpoint=\"{}\"), {}",
|
|
1834
1830
|
log_prefix_,
|
|
1835
1831
|
config_text.size(),
|
|
1836
|
-
bootstrap_hostname_,
|
|
1837
|
-
|
|
1838
|
-
|
|
1832
|
+
logger::system_data(fmt::format("{}:{}", bootstrap_hostname_, bootstrap_port_number_)),
|
|
1833
|
+
// an opt-in dump, it exists to show the exact bytes. That is the
|
|
1834
|
+
// "none at all" case of the rule in redaction.hxx.
|
|
1835
|
+
logger::not_redacted(config_text));
|
|
1839
1836
|
}
|
|
1840
1837
|
auto config =
|
|
1841
1838
|
protocol::parse_config(config_text, bootstrap_hostname_, bootstrap_port_number_);
|
|
@@ -1843,7 +1840,7 @@ public:
|
|
|
1843
1840
|
"{} received not_my_vbucket status for {}, opaque={} with config rev={} in the payload",
|
|
1844
1841
|
log_prefix_,
|
|
1845
1842
|
protocol::client_opcode(msg.header.opcode),
|
|
1846
|
-
utils::
|
|
1843
|
+
utils::network_to_host(msg.header.opaque),
|
|
1847
1844
|
config.rev_str());
|
|
1848
1845
|
update_configuration(std::move(config));
|
|
1849
1846
|
}
|
|
@@ -1863,15 +1860,19 @@ public:
|
|
|
1863
1860
|
collection_cache_.update(path, uid);
|
|
1864
1861
|
}
|
|
1865
1862
|
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1863
|
+
private:
|
|
1864
|
+
/**
|
|
1865
|
+
* The bucket name for the log prefix, or an untagged "-" when the session is not bound to a
|
|
1866
|
+
* bucket.
|
|
1867
|
+
*/
|
|
1868
|
+
[[nodiscard]] auto log_prefix_bucket_name() const -> std::string
|
|
1869
1869
|
{
|
|
1870
|
-
|
|
1870
|
+
if (!bucket_name_.has_value()) {
|
|
1871
|
+
return "-";
|
|
1872
|
+
}
|
|
1873
|
+
return fmt::format("{}", logger::metadata(bucket_name_.value()));
|
|
1871
1874
|
}
|
|
1872
|
-
#endif
|
|
1873
1875
|
|
|
1874
|
-
private:
|
|
1875
1876
|
void invoke_bootstrap_handler(std::error_code ec)
|
|
1876
1877
|
{
|
|
1877
1878
|
connection_deadline_.cancel();
|
|
@@ -1961,10 +1962,9 @@ private:
|
|
|
1961
1962
|
return initiate_bootstrap();
|
|
1962
1963
|
}
|
|
1963
1964
|
endpoints_ = endpoints;
|
|
1964
|
-
CB_LOG_TRACE("{} resolved \"{}
|
|
1965
|
+
CB_LOG_TRACE("{} resolved \"{}\" to {} endpoint(s)",
|
|
1965
1966
|
log_prefix_,
|
|
1966
|
-
|
|
1967
|
-
bootstrap_port_,
|
|
1967
|
+
logger::system_data(bootstrap_address_),
|
|
1968
1968
|
endpoints_.size());
|
|
1969
1969
|
do_connect(endpoints_.begin());
|
|
1970
1970
|
}
|
|
@@ -1978,12 +1978,10 @@ private:
|
|
|
1978
1978
|
if (it != endpoints_.end()) {
|
|
1979
1979
|
auto hostname = it->endpoint().address().to_string();
|
|
1980
1980
|
auto port = it->endpoint().port();
|
|
1981
|
-
CB_LOG_DEBUG("{} connecting to {}
|
|
1981
|
+
CB_LOG_DEBUG("{} connecting to {} (\"{}\"), timeout={}ms",
|
|
1982
1982
|
log_prefix_,
|
|
1983
|
-
hostname,
|
|
1984
|
-
|
|
1985
|
-
bootstrap_hostname_,
|
|
1986
|
-
bootstrap_port_,
|
|
1983
|
+
logger::system_data(fmt::format("{}:{}", hostname, port)),
|
|
1984
|
+
logger::system_data(bootstrap_address_),
|
|
1987
1985
|
origin_.options().connect_timeout.count());
|
|
1988
1986
|
connection_deadline_.expires_after(origin_.options().connect_timeout);
|
|
1989
1987
|
connection_deadline_.async_wait(
|
|
@@ -1991,17 +1989,16 @@ private:
|
|
|
1991
1989
|
if (timer_ec == asio::error::operation_aborted || self->stopped_) {
|
|
1992
1990
|
return;
|
|
1993
1991
|
}
|
|
1994
|
-
CB_LOG_DEBUG("{} unable to connect to {}
|
|
1992
|
+
CB_LOG_DEBUG("{} unable to connect to {} (\"{}\") in time, reconnecting",
|
|
1995
1993
|
self->log_prefix_,
|
|
1996
|
-
hostname,
|
|
1997
|
-
|
|
1998
|
-
self->bootstrap_hostname_,
|
|
1999
|
-
self->bootstrap_port_);
|
|
1994
|
+
logger::system_data(fmt::format("{}:{}", hostname, port)),
|
|
1995
|
+
logger::system_data(self->bootstrap_address_));
|
|
2000
1996
|
self->initiate_bootstrap();
|
|
2001
1997
|
});
|
|
2002
|
-
stream_->async_connect(
|
|
2003
|
-
|
|
2004
|
-
|
|
1998
|
+
stream_->async_connect(
|
|
1999
|
+
it->endpoint(), bootstrap_hostname_, [self = shared_from_this(), it](auto&& ec) {
|
|
2000
|
+
self->on_connect(std::forward<decltype(ec)>(ec), it);
|
|
2001
|
+
});
|
|
2005
2002
|
} else {
|
|
2006
2003
|
auto error_msg =
|
|
2007
2004
|
fmt::format("no more endpoints left to connect to \"{}:{}\", will try another address",
|
|
@@ -2037,10 +2034,10 @@ private:
|
|
|
2037
2034
|
? ERR_error_string(static_cast<unsigned long>(ec.value()), nullptr)
|
|
2038
2035
|
: ec.message();
|
|
2039
2036
|
#endif
|
|
2040
|
-
CB_LOG_WARNING("{} unable to connect to {}:
|
|
2037
|
+
CB_LOG_WARNING("{} unable to connect to {}: {} ({}){}. is_open={}",
|
|
2041
2038
|
log_prefix_,
|
|
2042
|
-
|
|
2043
|
-
|
|
2039
|
+
logger::system_data(fmt::format(
|
|
2040
|
+
"{}:{}", it->endpoint().address().to_string(), it->endpoint().port())),
|
|
2044
2041
|
ec.value(),
|
|
2045
2042
|
error_message,
|
|
2046
2043
|
(ec == asio::error::connection_refused)
|
|
@@ -2051,10 +2048,11 @@ private:
|
|
|
2051
2048
|
stream_->close([self = shared_from_this(), next_address = ++it](std::error_code ec) {
|
|
2052
2049
|
if (ec) {
|
|
2053
2050
|
CB_LOG_WARNING(
|
|
2054
|
-
"{} unable to close socket, but continue connecting attempt to {}:
|
|
2051
|
+
"{} unable to close socket, but continue connecting attempt to {}: {}",
|
|
2055
2052
|
self->log_prefix_,
|
|
2056
|
-
|
|
2057
|
-
|
|
2053
|
+
logger::system_data(fmt::format("{}:{}",
|
|
2054
|
+
next_address->endpoint().address().to_string(),
|
|
2055
|
+
next_address->endpoint().port())),
|
|
2058
2056
|
ec.value());
|
|
2059
2057
|
}
|
|
2060
2058
|
self->do_connect(next_address);
|
|
@@ -2065,24 +2063,31 @@ private:
|
|
|
2065
2063
|
} else {
|
|
2066
2064
|
stream_->set_options();
|
|
2067
2065
|
connection_endpoints_ = { it->endpoint(), stream_->local_endpoint() };
|
|
2068
|
-
CB_LOG_DEBUG("{} connected to {}
|
|
2066
|
+
CB_LOG_DEBUG("{} connected to {}",
|
|
2069
2067
|
log_prefix_,
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
client_id_,
|
|
2075
|
-
id_,
|
|
2076
|
-
stream_->log_prefix(),
|
|
2077
|
-
bucket_name_.value_or("-"),
|
|
2078
|
-
connection_endpoints_.local.port(),
|
|
2079
|
-
bootstrap_hostname_,
|
|
2080
|
-
connection_endpoints_.remote_address,
|
|
2081
|
-
connection_endpoints_.remote.port());
|
|
2082
|
-
parser_.reset();
|
|
2068
|
+
logger::system_data(fmt::format("{}:{}:{}",
|
|
2069
|
+
connection_endpoints_.local.port(),
|
|
2070
|
+
connection_endpoints_.remote_address,
|
|
2071
|
+
connection_endpoints_.remote.port())));
|
|
2083
2072
|
{
|
|
2084
|
-
const std::scoped_lock lock(
|
|
2085
|
-
|
|
2073
|
+
const std::scoped_lock lock(session_info_mutex_);
|
|
2074
|
+
const auto endpoints = fmt::format("{}:{}/{}:{}",
|
|
2075
|
+
connection_endpoints_.local.port(),
|
|
2076
|
+
bootstrap_hostname_,
|
|
2077
|
+
connection_endpoints_.remote_address,
|
|
2078
|
+
connection_endpoints_.remote.port());
|
|
2079
|
+
log_prefix_ = fmt::format("[{}/{}/{}/{}] <{}>",
|
|
2080
|
+
client_id_,
|
|
2081
|
+
id_,
|
|
2082
|
+
stream_->log_prefix(),
|
|
2083
|
+
log_prefix_bucket_name(),
|
|
2084
|
+
logger::system_data(endpoints));
|
|
2085
|
+
}
|
|
2086
|
+
parser_.reset();
|
|
2087
|
+
output_queue_.reset();
|
|
2088
|
+
// cppcheck-suppress knownConditionTrueFalse
|
|
2089
|
+
if (stopped_) {
|
|
2090
|
+
return;
|
|
2086
2091
|
}
|
|
2087
2092
|
bootstrap_handler_ = std::make_shared<bootstrap_handler>(shared_from_this());
|
|
2088
2093
|
|
|
@@ -2091,14 +2096,13 @@ private:
|
|
|
2091
2096
|
if (timer_ec == asio::error::operation_aborted || self->stopped_) {
|
|
2092
2097
|
return;
|
|
2093
2098
|
}
|
|
2094
|
-
CB_LOG_DEBUG(
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
self->bootstrap_port_);
|
|
2099
|
+
CB_LOG_DEBUG("{} unable to bootstrap single node at {} (\"{}\") in time, reconnecting",
|
|
2100
|
+
self->log_prefix_,
|
|
2101
|
+
logger::system_data(fmt::format("{}:{}:{}",
|
|
2102
|
+
self->connection_endpoints_.local.port(),
|
|
2103
|
+
self->connection_endpoints_.remote_address,
|
|
2104
|
+
self->connection_endpoints_.remote.port())),
|
|
2105
|
+
logger::system_data(self->bootstrap_address_));
|
|
2102
2106
|
return self->initiate_bootstrap();
|
|
2103
2107
|
});
|
|
2104
2108
|
}
|
|
@@ -2160,6 +2164,10 @@ private:
|
|
|
2160
2164
|
|
|
2161
2165
|
for (;;) {
|
|
2162
2166
|
mcbp_message msg{};
|
|
2167
|
+
// Start from a recycled buffer (if any) and tag the message with the pool so the frame
|
|
2168
|
+
// buffer is returned when the decoded response is destroyed on this IO thread.
|
|
2169
|
+
msg.body = tls_response_body_pool().acquire();
|
|
2170
|
+
msg.recycle_body = true;
|
|
2163
2171
|
switch (self->parser_.next(msg)) {
|
|
2164
2172
|
case mcbp_parser::result::ok: {
|
|
2165
2173
|
if (self->stopped_) {
|
|
@@ -2167,16 +2175,26 @@ private:
|
|
|
2167
2175
|
}
|
|
2168
2176
|
CB_LOG_TRACE(
|
|
2169
2177
|
"{} MCBP recv {}", self->log_prefix_, mcbp_header_view(msg.header_data()));
|
|
2178
|
+
// Copy the handler's shared_ptr into a local before dispatching.
|
|
2179
|
+
// handle() can trigger a nested stop() (e.g. reauth failure) that
|
|
2180
|
+
// releases the session's own strong ref to the handler; the local
|
|
2181
|
+
// copy keeps it alive for the duration of the call so it is not
|
|
2182
|
+
// freed mid-dispatch (CXXCBC-842).
|
|
2170
2183
|
if (self->bootstrapped_) {
|
|
2171
|
-
self->handler_
|
|
2172
|
-
|
|
2173
|
-
|
|
2184
|
+
if (auto h = self->handler_; h) {
|
|
2185
|
+
h->handle(std::move(msg));
|
|
2186
|
+
}
|
|
2187
|
+
} else if (auto h = self->bootstrap_handler_; h) {
|
|
2188
|
+
h->handle(std::move(msg));
|
|
2174
2189
|
}
|
|
2175
2190
|
if (self->stopped_) {
|
|
2176
2191
|
return;
|
|
2177
2192
|
}
|
|
2178
2193
|
} break;
|
|
2179
2194
|
case mcbp_parser::result::need_data:
|
|
2195
|
+
// The frame is incomplete, so next() did not consume the buffer we handed it; return
|
|
2196
|
+
// it to the pool instead of letting this partial-read iteration drain the pool.
|
|
2197
|
+
tls_response_body_pool().release(std::move(msg.body));
|
|
2180
2198
|
self->reading_ = false;
|
|
2181
2199
|
if (!self->stopped_ && self->stream_->is_open()) {
|
|
2182
2200
|
self->do_read();
|
|
@@ -2194,14 +2212,12 @@ private:
|
|
|
2194
2212
|
if (stopped_ || !stream_->is_open()) {
|
|
2195
2213
|
return;
|
|
2196
2214
|
}
|
|
2197
|
-
|
|
2198
|
-
if (!writing_buffer_.empty() || output_buffer_.empty()) {
|
|
2215
|
+
if (!output_queue_.begin_writing()) {
|
|
2199
2216
|
return;
|
|
2200
2217
|
}
|
|
2201
|
-
std::swap(writing_buffer_, output_buffer_);
|
|
2202
2218
|
std::vector<asio::const_buffer> buffers;
|
|
2203
|
-
buffers.reserve(
|
|
2204
|
-
for (auto& buf :
|
|
2219
|
+
buffers.reserve(output_queue_.writing().size());
|
|
2220
|
+
for (const auto& buf : output_queue_.writing()) {
|
|
2205
2221
|
CB_LOG_PROTOCOL("[MCBP, OUT] host=\"{}\", sport={}, dport={}, buffer_size={}{:a}",
|
|
2206
2222
|
connection_endpoints_.remote_address,
|
|
2207
2223
|
connection_endpoints_.local.port(),
|
|
@@ -2231,10 +2247,7 @@ private:
|
|
|
2231
2247
|
ec.message());
|
|
2232
2248
|
return self->stop(retry_reason::socket_closed_while_in_flight);
|
|
2233
2249
|
}
|
|
2234
|
-
|
|
2235
|
-
const std::scoped_lock inner_lock(self->writing_buffer_mutex_);
|
|
2236
|
-
self->writing_buffer_.clear();
|
|
2237
|
-
}
|
|
2250
|
+
self->output_queue_.finish_writing();
|
|
2238
2251
|
asio::post(asio::bind_executor(self->ctx_, [self]() {
|
|
2239
2252
|
self->do_write();
|
|
2240
2253
|
self->do_read();
|
|
@@ -2244,6 +2257,7 @@ private:
|
|
|
2244
2257
|
|
|
2245
2258
|
const std::string client_id_;
|
|
2246
2259
|
std::string node_uuid_;
|
|
2260
|
+
app_telemetry_recorder_cache app_telemetry_recorder_cache_{};
|
|
2247
2261
|
const std::string id_{ uuid::to_string(uuid::random()) };
|
|
2248
2262
|
asio::io_context& ctx_;
|
|
2249
2263
|
asio::ip::tcp::resolver resolver_;
|
|
@@ -2263,7 +2277,7 @@ private:
|
|
|
2263
2277
|
utils::movable_function<void(std::error_code, const topology::configuration&)>
|
|
2264
2278
|
bootstrap_callback_{};
|
|
2265
2279
|
std::mutex command_handlers_mutex_{};
|
|
2266
|
-
|
|
2280
|
+
opaque_ring_table<command_handler> command_handlers_{};
|
|
2267
2281
|
std::vector<std::shared_ptr<config_listener>> config_listeners_{};
|
|
2268
2282
|
utils::movable_function<void()> on_stop_handler_{};
|
|
2269
2283
|
|
|
@@ -2278,18 +2292,16 @@ private:
|
|
|
2278
2292
|
std::atomic<std::uint32_t> opaque_{ 0 };
|
|
2279
2293
|
|
|
2280
2294
|
std::array<std::byte, 16384> input_buffer_{};
|
|
2281
|
-
|
|
2295
|
+
mcbp_output_queue output_queue_{};
|
|
2282
2296
|
std::vector<std::vector<std::byte>> pending_buffer_{};
|
|
2283
|
-
std::vector<std::vector<std::byte>> writing_buffer_{};
|
|
2284
|
-
std::mutex output_buffer_mutex_{};
|
|
2285
2297
|
std::mutex pending_buffer_mutex_{};
|
|
2286
|
-
std::mutex writing_buffer_mutex_{};
|
|
2287
2298
|
std::string bootstrap_hostname_{};
|
|
2288
2299
|
std::string bootstrap_port_{};
|
|
2289
2300
|
std::string bootstrap_address_{};
|
|
2290
2301
|
std::uint16_t bootstrap_port_number_{};
|
|
2291
2302
|
connection_endpoints connection_endpoints_{ {}, {} };
|
|
2292
2303
|
asio::ip::tcp::resolver::results_type endpoints_;
|
|
2304
|
+
mutable std::mutex session_info_mutex_{};
|
|
2293
2305
|
std::vector<protocol::hello_feature> supported_features_;
|
|
2294
2306
|
std::optional<topology::configuration> config_;
|
|
2295
2307
|
mutable std::mutex config_mutex_{};
|
|
@@ -2315,11 +2327,6 @@ private:
|
|
|
2315
2327
|
std::string log_prefix_{};
|
|
2316
2328
|
std::chrono::time_point<std::chrono::steady_clock> last_active_{};
|
|
2317
2329
|
std::atomic<diag::endpoint_state> state_{ diag::endpoint_state::disconnected };
|
|
2318
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
2319
|
-
std::shared_ptr<columnar::background_bootstrap_listener> background_bootstrap_listener_{
|
|
2320
|
-
nullptr
|
|
2321
|
-
};
|
|
2322
|
-
#endif
|
|
2323
2330
|
};
|
|
2324
2331
|
|
|
2325
2332
|
mcbp_session::mcbp_session(const std::string& client_id,
|
|
@@ -2358,8 +2365,13 @@ mcbp_session::mcbp_session(const std::string& client_id,
|
|
|
2358
2365
|
{
|
|
2359
2366
|
}
|
|
2360
2367
|
|
|
2368
|
+
mcbp_session::mcbp_session(std::shared_ptr<mcbp_session_impl> impl)
|
|
2369
|
+
: impl_{ std::move(impl) }
|
|
2370
|
+
{
|
|
2371
|
+
}
|
|
2372
|
+
|
|
2361
2373
|
auto
|
|
2362
|
-
mcbp_session::log_prefix() const ->
|
|
2374
|
+
mcbp_session::log_prefix() const -> std::string
|
|
2363
2375
|
{
|
|
2364
2376
|
return impl_->log_prefix();
|
|
2365
2377
|
}
|
|
@@ -2418,6 +2430,14 @@ mcbp_session::node_uuid() const -> const std::string&
|
|
|
2418
2430
|
return impl_->node_uuid();
|
|
2419
2431
|
}
|
|
2420
2432
|
|
|
2433
|
+
auto
|
|
2434
|
+
mcbp_session::app_telemetry_recorder(app_telemetry_meter& meter,
|
|
2435
|
+
const std::string& bucket_name) const
|
|
2436
|
+
-> std::shared_ptr<app_telemetry_value_recorder>
|
|
2437
|
+
{
|
|
2438
|
+
return impl_->app_telemetry_recorder(meter, bucket_name);
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2421
2441
|
auto
|
|
2422
2442
|
mcbp_session::bootstrap_address() const -> const std::string&
|
|
2423
2443
|
{
|
|
@@ -2466,18 +2486,6 @@ mcbp_session::bootstrap_port_number() const -> std::uint16_t
|
|
|
2466
2486
|
return impl_->bootstrap_port_number();
|
|
2467
2487
|
}
|
|
2468
2488
|
|
|
2469
|
-
auto
|
|
2470
|
-
mcbp_session::last_bootstrap_error() && -> std::optional<impl::bootstrap_error>
|
|
2471
|
-
{
|
|
2472
|
-
return std::move(impl_)->last_bootstrap_error();
|
|
2473
|
-
}
|
|
2474
|
-
|
|
2475
|
-
auto
|
|
2476
|
-
mcbp_session::last_bootstrap_error() const& -> const std::optional<impl::bootstrap_error>&
|
|
2477
|
-
{
|
|
2478
|
-
return impl_->last_bootstrap_error();
|
|
2479
|
-
}
|
|
2480
|
-
|
|
2481
2489
|
auto
|
|
2482
2490
|
mcbp_session::canonical_hostname() const -> const std::string&
|
|
2483
2491
|
{
|
|
@@ -2610,13 +2618,4 @@ mcbp_session::write_and_flush(std::vector<std::byte>&& buffer)
|
|
|
2610
2618
|
return impl_->write_and_flush(std::move(buffer));
|
|
2611
2619
|
}
|
|
2612
2620
|
|
|
2613
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
2614
|
-
void
|
|
2615
|
-
mcbp_session::add_background_bootstrap_listener(
|
|
2616
|
-
std::shared_ptr<columnar::background_bootstrap_listener> listener)
|
|
2617
|
-
{
|
|
2618
|
-
return impl_->add_background_bootstrap_listener(std::move(listener));
|
|
2619
|
-
}
|
|
2620
|
-
#endif
|
|
2621
|
-
|
|
2622
2621
|
} // namespace couchbase::core::io
|