couchbase 3.7.0 → 3.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/ext/CMakeLists.txt +4 -1
- data/ext/cache/extconf_include.rb +4 -3
- data/ext/cache/mozilla-ca-bundle.crt +66 -665
- data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
- data/ext/couchbase/CMakeLists.txt +26 -11
- data/ext/couchbase/cmake/APKBUILD.in +17 -1
- data/ext/couchbase/cmake/Bundler.cmake +9 -1
- data/ext/couchbase/cmake/Cache.cmake +48 -19
- data/ext/couchbase/cmake/CompilerOptions.cmake +3 -1
- data/ext/couchbase/cmake/OpenSSL.cmake +10 -2
- data/ext/couchbase/cmake/Packaging.cmake +48 -8
- data/ext/couchbase/cmake/ThirdPartyDependencies.cmake +43 -1
- data/ext/couchbase/cmake/build_config.hxx.in +2 -0
- data/ext/couchbase/cmake/couchbase-cxx-client.spec.in +18 -0
- data/ext/couchbase/cmake/tarball_glob.txt +10 -0
- data/ext/couchbase/core/app_telemetry_meter.cxx +1 -0
- data/ext/couchbase/core/app_telemetry_reporter.cxx +45 -43
- data/ext/couchbase/core/app_telemetry_reporter.hxx +4 -3
- data/ext/couchbase/core/bucket.cxx +128 -13
- data/ext/couchbase/core/bucket.hxx +12 -2
- data/ext/couchbase/core/cluster.cxx +304 -152
- data/ext/couchbase/core/cluster.hxx +32 -0
- data/ext/couchbase/core/cluster_credentials.cxx +25 -0
- data/ext/couchbase/core/cluster_credentials.hxx +5 -0
- data/ext/couchbase/core/cluster_label_listener.cxx +72 -0
- data/ext/couchbase/core/cluster_label_listener.hxx +46 -0
- data/ext/couchbase/core/cluster_options.hxx +4 -0
- data/ext/couchbase/core/deprecation_utils.hxx +26 -0
- data/ext/couchbase/core/error.hxx +27 -0
- data/ext/couchbase/core/error_context/base_error_context.hxx +32 -0
- data/ext/couchbase/core/error_context/key_value.cxx +1 -0
- data/ext/couchbase/core/error_context/key_value.hxx +23 -0
- data/ext/couchbase/core/error_context/key_value_error_context.hxx +35 -0
- data/ext/couchbase/core/error_context/subdocument_error_context.hxx +41 -0
- data/ext/couchbase/core/free_form_http_request.hxx +0 -2
- data/ext/couchbase/core/http_component.cxx +12 -48
- data/ext/couchbase/core/impl/analytics.cxx +3 -2
- data/ext/couchbase/core/impl/analytics.hxx +2 -1
- data/ext/couchbase/core/impl/analytics_index_manager.cxx +249 -137
- data/ext/couchbase/core/impl/binary_collection.cxx +239 -128
- data/ext/couchbase/core/impl/bucket_manager.cxx +87 -35
- data/ext/couchbase/core/impl/collection.cxx +914 -372
- data/ext/couchbase/core/impl/collection_manager.cxx +89 -49
- data/ext/couchbase/core/impl/dns_srv_tracker.cxx +4 -4
- data/ext/couchbase/core/impl/error.cxx +49 -17
- data/ext/couchbase/core/impl/error.hxx +15 -10
- data/ext/couchbase/core/impl/get_all_replicas.hxx +1 -1
- data/ext/couchbase/core/impl/get_any_replica.hxx +2 -1
- data/ext/couchbase/core/impl/get_replica.hxx +2 -0
- data/ext/couchbase/core/impl/invoke_with_node_id.hxx +44 -0
- data/ext/couchbase/core/impl/lookup_in_replica.hxx +1 -1
- data/ext/couchbase/core/impl/node_id.cxx +110 -0
- data/ext/couchbase/core/impl/node_id.hxx +40 -0
- data/ext/couchbase/core/impl/observability_recorder.cxx +161 -0
- data/ext/couchbase/core/impl/observability_recorder.hxx +77 -0
- data/ext/couchbase/core/impl/observe_seqno.hxx +2 -0
- data/ext/couchbase/core/impl/public_bucket.cxx +31 -7
- data/ext/couchbase/core/impl/public_cluster.cxx +107 -19
- data/ext/couchbase/core/impl/query.cxx +6 -3
- data/ext/couchbase/core/impl/query.hxx +3 -1
- data/ext/couchbase/core/impl/query_index_manager.cxx +267 -102
- data/ext/couchbase/core/impl/scope.cxx +53 -11
- data/ext/couchbase/core/impl/search.cxx +8 -4
- data/ext/couchbase/core/impl/search.hxx +6 -2
- data/ext/couchbase/core/impl/search_index_manager.cxx +131 -41
- data/ext/couchbase/core/impl/with_cancellation.hxx +75 -0
- data/ext/couchbase/core/io/config_tracker.cxx +9 -9
- data/ext/couchbase/core/io/config_tracker.hxx +2 -1
- data/ext/couchbase/core/io/http_command.hxx +98 -49
- data/ext/couchbase/core/io/http_context.hxx +2 -0
- data/ext/couchbase/core/io/http_session.cxx +23 -10
- data/ext/couchbase/core/io/http_session.hxx +17 -9
- data/ext/couchbase/core/io/http_session_manager.hxx +245 -270
- data/ext/couchbase/core/io/http_traits.hxx +0 -7
- data/ext/couchbase/core/io/mcbp_command.hxx +123 -44
- data/ext/couchbase/core/io/mcbp_session.cxx +251 -26
- data/ext/couchbase/core/io/mcbp_session.hxx +9 -1
- data/ext/couchbase/core/io/mcbp_traits.hxx +0 -8
- data/ext/couchbase/core/io/streams.cxx +3 -3
- data/ext/couchbase/core/io/streams.hxx +3 -2
- data/ext/couchbase/core/meta/features.hxx +15 -0
- data/ext/couchbase/core/meta/version.cxx +13 -0
- data/ext/couchbase/core/meta/version.hxx +3 -0
- data/ext/couchbase/core/metrics/constants.hxx +23 -0
- data/ext/couchbase/core/metrics/logging_meter.cxx +5 -5
- data/ext/couchbase/core/metrics/meter_wrapper.cxx +65 -63
- data/ext/couchbase/core/metrics/meter_wrapper.hxx +12 -10
- data/ext/couchbase/core/operations/document_analytics.hxx +0 -5
- data/ext/couchbase/core/operations/document_append.hxx +0 -4
- data/ext/couchbase/core/operations/document_decrement.hxx +0 -5
- data/ext/couchbase/core/operations/document_exists.hxx +0 -7
- data/ext/couchbase/core/operations/document_get.hxx +0 -7
- data/ext/couchbase/core/operations/document_get_all_replicas.hxx +89 -29
- data/ext/couchbase/core/operations/document_get_and_lock.hxx +0 -9
- data/ext/couchbase/core/operations/document_get_and_touch.hxx +0 -9
- data/ext/couchbase/core/operations/document_get_any_replica.hxx +83 -2
- data/ext/couchbase/core/operations/document_get_projected.cxx +3 -4
- data/ext/couchbase/core/operations/document_get_projected.hxx +0 -9
- data/ext/couchbase/core/operations/document_increment.hxx +0 -5
- data/ext/couchbase/core/operations/document_insert.hxx +0 -4
- data/ext/couchbase/core/operations/document_lookup_in.hxx +0 -9
- data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +50 -4
- data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +121 -43
- data/ext/couchbase/core/operations/document_mutate_in.hxx +0 -5
- data/ext/couchbase/core/operations/document_prepend.hxx +0 -4
- data/ext/couchbase/core/operations/document_query.cxx +12 -12
- data/ext/couchbase/core/operations/document_query.hxx +0 -4
- data/ext/couchbase/core/operations/document_remove.hxx +0 -4
- data/ext/couchbase/core/operations/document_replace.hxx +0 -4
- data/ext/couchbase/core/operations/document_search.hxx +0 -7
- data/ext/couchbase/core/operations/document_touch.hxx +0 -7
- data/ext/couchbase/core/operations/document_unlock.hxx +0 -6
- data/ext/couchbase/core/operations/document_upsert.hxx +0 -4
- data/ext/couchbase/core/operations/document_view.cxx +2 -0
- data/ext/couchbase/core/operations/document_view.hxx +10 -13
- data/ext/couchbase/core/operations/http_noop.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_dataset_create.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_dataset_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_dataset_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_dataverse_create.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_dataverse_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_get_pending_mutations.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_index_create.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_index_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_index_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_link_connect.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_link_create.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_link_disconnect.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_link_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_link_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/analytics_link_replace.hxx +2 -0
- data/ext/couchbase/core/operations/management/bucket_create.hxx +2 -0
- data/ext/couchbase/core/operations/management/bucket_describe.hxx +2 -0
- data/ext/couchbase/core/operations/management/bucket_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/bucket_flush.hxx +2 -0
- data/ext/couchbase/core/operations/management/bucket_get.hxx +2 -0
- data/ext/couchbase/core/operations/management/bucket_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/bucket_update.hxx +2 -0
- data/ext/couchbase/core/operations/management/change_password.hxx +2 -0
- data/ext/couchbase/core/operations/management/cluster_describe.hxx +2 -0
- data/ext/couchbase/core/operations/management/cluster_developer_preview_enable.hxx +2 -0
- data/ext/couchbase/core/operations/management/collection_create.cxx +11 -11
- data/ext/couchbase/core/operations/management/collection_create.hxx +2 -0
- data/ext/couchbase/core/operations/management/collection_drop.cxx +11 -11
- data/ext/couchbase/core/operations/management/collection_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/collection_update.cxx +11 -11
- data/ext/couchbase/core/operations/management/collection_update.hxx +2 -0
- data/ext/couchbase/core/operations/management/collections_manifest_get.hxx +2 -0
- data/ext/couchbase/core/operations/management/error_utils.cxx +13 -7
- data/ext/couchbase/core/operations/management/eventing_deploy_function.hxx +2 -0
- data/ext/couchbase/core/operations/management/eventing_drop_function.hxx +2 -0
- data/ext/couchbase/core/operations/management/eventing_get_all_functions.hxx +2 -0
- data/ext/couchbase/core/operations/management/eventing_get_function.hxx +2 -0
- data/ext/couchbase/core/operations/management/eventing_get_status.hxx +2 -0
- data/ext/couchbase/core/operations/management/eventing_pause_function.hxx +2 -0
- data/ext/couchbase/core/operations/management/eventing_resume_function.hxx +2 -0
- data/ext/couchbase/core/operations/management/eventing_undeploy_function.hxx +2 -0
- data/ext/couchbase/core/operations/management/eventing_upsert_function.hxx +2 -0
- data/ext/couchbase/core/operations/management/freeform.hxx +2 -0
- data/ext/couchbase/core/operations/management/group_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/group_get.hxx +2 -0
- data/ext/couchbase/core/operations/management/group_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/group_upsert.hxx +2 -0
- data/ext/couchbase/core/operations/management/query_index_build.hxx +2 -0
- data/ext/couchbase/core/operations/management/query_index_build_deferred.hxx +68 -30
- data/ext/couchbase/core/operations/management/query_index_create.cxx +5 -4
- data/ext/couchbase/core/operations/management/query_index_create.hxx +2 -0
- data/ext/couchbase/core/operations/management/query_index_drop.cxx +7 -6
- data/ext/couchbase/core/operations/management/query_index_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/query_index_get_all.hxx +4 -3
- data/ext/couchbase/core/operations/management/query_index_get_all_deferred.hxx +2 -1
- data/ext/couchbase/core/operations/management/role_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/scope_create.cxx +12 -13
- data/ext/couchbase/core/operations/management/scope_create.hxx +2 -0
- data/ext/couchbase/core/operations/management/scope_drop.cxx +8 -9
- data/ext/couchbase/core/operations/management/scope_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/scope_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_get_stats.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_analyze_document.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_control_ingest.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_control_query.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_get.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_get_documents_count.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_get_stats.hxx +2 -0
- data/ext/couchbase/core/operations/management/search_index_upsert.hxx +2 -0
- data/ext/couchbase/core/operations/management/user_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/user_get.hxx +2 -0
- data/ext/couchbase/core/operations/management/user_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/user_upsert.hxx +2 -0
- data/ext/couchbase/core/operations/management/view_index_drop.hxx +2 -0
- data/ext/couchbase/core/operations/management/view_index_get.hxx +2 -0
- data/ext/couchbase/core/operations/management/view_index_get_all.hxx +2 -0
- data/ext/couchbase/core/operations/management/view_index_upsert.hxx +2 -0
- data/ext/couchbase/core/operations/operation_traits.hxx +6 -0
- data/ext/couchbase/core/operations.hxx +0 -1
- data/ext/couchbase/core/operations_fwd.hxx +8 -0
- data/ext/couchbase/core/origin.cxx +67 -12
- data/ext/couchbase/core/origin.hxx +13 -8
- data/ext/couchbase/core/orphan_reporter.cxx +164 -0
- data/ext/couchbase/core/orphan_reporter.hxx +65 -0
- data/ext/couchbase/core/sasl/CMakeLists.txt +1 -0
- data/ext/couchbase/core/sasl/client.cc +6 -0
- data/ext/couchbase/core/sasl/mechanism.cc +2 -1
- data/ext/couchbase/core/sasl/mechanism.h +2 -1
- data/ext/couchbase/core/sasl/oauthbearer/oauthbearer.cc +41 -0
- data/ext/couchbase/core/sasl/oauthbearer/oauthbearer.h +47 -0
- data/ext/couchbase/core/tls_context_provider.cxx +44 -0
- data/ext/couchbase/core/tls_context_provider.hxx +44 -0
- data/ext/couchbase/core/topology/configuration.cxx +21 -0
- data/ext/couchbase/core/topology/configuration.hxx +28 -0
- data/ext/couchbase/core/tracing/attribute_helpers.hxx +45 -0
- data/ext/couchbase/core/tracing/constants.hxx +148 -68
- data/ext/couchbase/core/tracing/threshold_logging_options.hxx +0 -3
- data/ext/couchbase/core/tracing/threshold_logging_tracer.cxx +122 -170
- data/ext/couchbase/core/tracing/tracer_wrapper.cxx +17 -24
- data/ext/couchbase/core/tracing/tracer_wrapper.hxx +8 -10
- data/ext/couchbase/core/tracing/wrapper_sdk_tracer.cxx +114 -0
- data/ext/couchbase/core/tracing/wrapper_sdk_tracer.hxx +85 -0
- data/ext/couchbase/core/transactions/attempt_context_impl.cxx +16 -14
- data/ext/couchbase/core/transactions/attempt_context_impl.hxx +4 -4
- data/ext/couchbase/core/transactions/transactions.cxx +1 -1
- data/ext/couchbase/core/transactions/transactions_cleanup.cxx +1 -2
- data/ext/couchbase/core/utils/byteswap.hxx +12 -0
- data/ext/couchbase/core/utils/concurrent_fixed_priority_queue.hxx +102 -0
- data/ext/couchbase/core/utils/connection_string.cxx +2 -0
- data/ext/couchbase/core/utils/contains_string.cxx +61 -0
- data/ext/couchbase/core/utils/contains_string.hxx +26 -0
- data/ext/couchbase/couchbase/certificate_authenticator.hxx +1 -0
- data/ext/couchbase/couchbase/cluster.hxx +47 -0
- data/ext/couchbase/couchbase/cluster_options.hxx +16 -0
- data/ext/couchbase/couchbase/collection.hxx +133 -15
- data/ext/couchbase/couchbase/error.hxx +16 -0
- data/ext/couchbase/couchbase/error_codes.hxx +48 -48
- data/ext/couchbase/couchbase/jwt_authenticator.hxx +52 -0
- data/ext/couchbase/couchbase/metrics/meter.hxx +2 -1
- data/ext/couchbase/couchbase/metrics/otel_meter.hxx +75 -80
- data/ext/couchbase/couchbase/network_options.hxx +19 -0
- data/ext/couchbase/couchbase/node_id.hxx +123 -0
- data/ext/couchbase/couchbase/node_id_for_options.hxx +61 -0
- data/ext/couchbase/couchbase/node_ids_options.hxx +62 -0
- data/ext/couchbase/couchbase/password_authenticator.hxx +1 -0
- data/ext/couchbase/couchbase/result.hxx +42 -0
- data/ext/couchbase/couchbase/tracing/otel_tracer.hxx +15 -17
- data/ext/couchbase/couchbase/tracing/request_span.hxx +2 -2
- data/ext/couchbase.cxx +4 -0
- data/ext/extconf.rb +1 -0
- data/ext/rcb_analytics.cxx +157 -47
- data/ext/rcb_backend.cxx +118 -71
- data/ext/rcb_buckets.cxx +39 -16
- data/ext/rcb_collections.cxx +36 -12
- data/ext/rcb_crud.cxx +589 -294
- data/ext/rcb_hdr_histogram.cxx +219 -0
- data/ext/rcb_hdr_histogram.hxx +28 -0
- data/ext/rcb_logger.cxx +15 -17
- data/ext/rcb_multi.cxx +142 -59
- data/ext/rcb_observability.cxx +132 -0
- data/ext/rcb_observability.hxx +49 -0
- data/ext/rcb_query.cxx +77 -27
- data/ext/rcb_search.cxx +92 -31
- data/ext/rcb_users.cxx +69 -26
- data/ext/rcb_utils.cxx +91 -0
- data/ext/rcb_utils.hxx +141 -168
- data/ext/rcb_views.cxx +36 -12
- data/lib/active_support/cache/couchbase_store.rb +6 -6
- data/lib/couchbase/authenticator.rb +14 -0
- data/lib/couchbase/binary_collection.rb +37 -22
- data/lib/couchbase/bucket.rb +46 -31
- data/lib/couchbase/cluster.rb +146 -61
- data/lib/couchbase/collection.rb +257 -186
- data/lib/couchbase/datastructures/couchbase_list.rb +82 -50
- data/lib/couchbase/datastructures/couchbase_map.rb +87 -50
- data/lib/couchbase/datastructures/couchbase_queue.rb +65 -38
- data/lib/couchbase/datastructures/couchbase_set.rb +58 -41
- data/lib/couchbase/deprecations.rb +1 -1
- data/lib/couchbase/diagnostics.rb +8 -8
- data/lib/couchbase/errors.rb +7 -1
- data/lib/couchbase/json_transcoder.rb +1 -1
- data/lib/couchbase/management/analytics_index_manager.rb +90 -59
- data/lib/couchbase/management/bucket_manager.rb +73 -45
- data/lib/couchbase/management/collection_manager.rb +86 -43
- data/lib/couchbase/management/collection_query_index_manager.rb +56 -33
- data/lib/couchbase/management/query_index_manager.rb +88 -36
- data/lib/couchbase/management/scope_search_index_manager.rb +119 -52
- data/lib/couchbase/management/search_index_manager.rb +401 -178
- data/lib/couchbase/management/user_manager.rb +343 -174
- data/lib/couchbase/management/view_index_manager.rb +166 -73
- data/lib/couchbase/metrics/logging_meter.rb +108 -0
- data/lib/couchbase/metrics/logging_value_recorder.rb +50 -0
- data/lib/couchbase/metrics/meter.rb +27 -0
- data/lib/couchbase/metrics/noop_meter.rb +30 -0
- data/lib/couchbase/metrics/noop_value_recorder.rb +27 -0
- data/lib/couchbase/metrics/value_recorder.rb +25 -0
- data/lib/couchbase/options.rb +71 -5
- data/lib/couchbase/protostellar/client.rb +0 -2
- data/lib/couchbase/protostellar/cluster.rb +7 -0
- data/lib/couchbase/protostellar/generated/admin/analytics/v1/analytics_pb.rb +54 -0
- data/lib/couchbase/protostellar/generated/admin/analytics/v1/analytics_services_pb.rb +51 -0
- data/lib/couchbase/protostellar/generated/admin/bucket/v1/bucket_pb.rb +5 -24
- data/lib/couchbase/protostellar/generated/admin/bucket/v1/bucket_services_pb.rb +16 -0
- data/lib/couchbase/protostellar/generated/admin/collection/v1/collection_pb.rb +5 -24
- data/lib/couchbase/protostellar/generated/admin/collection/v1/collection_services_pb.rb +16 -0
- data/lib/couchbase/protostellar/generated/admin/query/v1/query_pb.rb +5 -24
- data/lib/couchbase/protostellar/generated/admin/query/v1/query_services_pb.rb +18 -0
- data/lib/couchbase/protostellar/generated/admin/search/v1/search_pb.rb +2 -23
- data/lib/couchbase/protostellar/generated/admin/search/v1/search_services_pb.rb +23 -0
- data/lib/couchbase/protostellar/generated/analytics/v1/analytics_pb.rb +4 -25
- data/lib/couchbase/protostellar/generated/analytics/v1/analytics_services_pb.rb +10 -0
- data/lib/couchbase/protostellar/generated/internal/hooks/v1/hooks_pb.rb +6 -25
- data/lib/couchbase/protostellar/generated/internal/hooks/v1/hooks_services_pb.rb +18 -0
- data/lib/couchbase/protostellar/generated/internal/xdcr/v1/xdcr_pb.rb +46 -0
- data/lib/couchbase/protostellar/generated/internal/xdcr/v1/xdcr_services_pb.rb +56 -0
- data/lib/couchbase/protostellar/generated/kv/v1/kv_pb.rb +3 -26
- data/lib/couchbase/protostellar/generated/kv/v1/kv_services_pb.rb +47 -0
- data/lib/couchbase/protostellar/generated/query/v1/query_pb.rb +4 -26
- data/lib/couchbase/protostellar/generated/query/v1/query_services_pb.rb +10 -0
- data/lib/couchbase/protostellar/generated/routing/v2/routing_pb.rb +26 -0
- data/lib/couchbase/protostellar/generated/routing/v2/routing_services_pb.rb +43 -0
- data/lib/couchbase/protostellar/generated/search/v1/search_pb.rb +5 -26
- data/lib/couchbase/protostellar/generated/search/v1/search_services_pb.rb +11 -0
- data/lib/couchbase/protostellar/generated/transactions/v1/transactions_pb.rb +2 -23
- data/lib/couchbase/protostellar/generated/transactions/v1/transactions_services_pb.rb +30 -0
- data/lib/couchbase/protostellar/generated/view/v1/view_pb.rb +2 -23
- data/lib/couchbase/protostellar/generated/view/v1/view_services_pb.rb +9 -0
- data/lib/couchbase/protostellar/request_generator/admin/collection.rb +4 -2
- data/lib/couchbase/protostellar/request_generator/admin/query.rb +2 -0
- data/lib/couchbase/protostellar/request_generator/kv.rb +1 -1
- data/lib/couchbase/protostellar/scope.rb +4 -0
- data/lib/couchbase/scope.rb +62 -48
- data/lib/couchbase/search_options.rb +18 -18
- data/lib/couchbase/tracing/noop_span.rb +29 -0
- data/lib/couchbase/tracing/noop_tracer.rb +29 -0
- data/lib/couchbase/tracing/request_span.rb +34 -0
- data/lib/couchbase/tracing/request_tracer.rb +28 -0
- data/lib/couchbase/tracing/threshold_logging_span.rb +112 -0
- data/lib/couchbase/tracing/threshold_logging_tracer.rb +231 -0
- data/lib/couchbase/utils/hdr_histogram.rb +55 -0
- data/lib/couchbase/utils/observability.rb +263 -0
- data/lib/couchbase/utils/observability_constants.rb +200 -0
- data/lib/couchbase/utils/stdlib_logger_adapter.rb +1 -3
- data/lib/couchbase/version.rb +1 -1
- data/lib/couchbase.rb +2 -2
- metadata +72 -8
- data/lib/couchbase/protostellar/generated/routing/v1/routing_pb.rb +0 -52
- data/lib/couchbase/protostellar/generated/routing/v1/routing_services_pb.rb +0 -30
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
#include "core/metrics/meter_wrapper.hxx"
|
|
29
29
|
#include "core/operations/http_noop.hxx"
|
|
30
30
|
#include "core/service_type.hxx"
|
|
31
|
+
#include "core/tls_context_provider.hxx"
|
|
31
32
|
#include "core/tracing/noop_tracer.hxx"
|
|
32
33
|
#include "core/tracing/tracer_wrapper.hxx"
|
|
33
34
|
#include "http_command.hxx"
|
|
@@ -58,10 +59,14 @@ class http_session_manager
|
|
|
58
59
|
{
|
|
59
60
|
#endif
|
|
60
61
|
public:
|
|
61
|
-
http_session_manager(std::string client_id,
|
|
62
|
+
http_session_manager(std::string client_id,
|
|
63
|
+
asio::io_context& ctx,
|
|
64
|
+
tls_context_provider& tls,
|
|
65
|
+
origin& origin)
|
|
62
66
|
: client_id_(std::move(client_id))
|
|
63
67
|
, ctx_(ctx)
|
|
64
68
|
, tls_(tls)
|
|
69
|
+
, origin_(origin)
|
|
65
70
|
{
|
|
66
71
|
}
|
|
67
72
|
|
|
@@ -192,8 +197,7 @@ public:
|
|
|
192
197
|
template<typename Collector>
|
|
193
198
|
void ping(std::set<service_type> services,
|
|
194
199
|
std::optional<std::chrono::milliseconds> timeout,
|
|
195
|
-
std::shared_ptr<Collector> collector
|
|
196
|
-
const couchbase::core::cluster_credentials& credentials)
|
|
200
|
+
std::shared_ptr<Collector> collector)
|
|
197
201
|
{
|
|
198
202
|
std::array known_types{
|
|
199
203
|
service_type::query, service_type::analytics, service_type::search,
|
|
@@ -212,7 +216,16 @@ public:
|
|
|
212
216
|
std::uint16_t port = node.port_or(options_.network, type, options_.enable_tls, 0);
|
|
213
217
|
if (port != 0) {
|
|
214
218
|
const auto& hostname = node.hostname_for(options_.network);
|
|
215
|
-
auto
|
|
219
|
+
const auto& canonical_hostname = node.hostname;
|
|
220
|
+
std::uint16_t canonical_port = node.port_or(type, options_.enable_tls, 0);
|
|
221
|
+
auto session = create_session(type,
|
|
222
|
+
node_details{
|
|
223
|
+
hostname,
|
|
224
|
+
port,
|
|
225
|
+
node.node_uuid,
|
|
226
|
+
canonical_hostname,
|
|
227
|
+
canonical_port,
|
|
228
|
+
});
|
|
216
229
|
if (session->is_connected()) {
|
|
217
230
|
std::scoped_lock lock(sessions_mutex_);
|
|
218
231
|
busy_sessions_[type].push_back(session);
|
|
@@ -238,66 +251,45 @@ public:
|
|
|
238
251
|
app_telemetry_meter_,
|
|
239
252
|
options_.default_timeout_for(request.type));
|
|
240
253
|
#endif
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
std::optional<std::string> error{};
|
|
251
|
-
if (!std::holds_alternative<std::monostate>(err)) {
|
|
252
|
-
auto ec = std::holds_alternative<impl::bootstrap_error>(err)
|
|
253
|
-
? std::get<impl::bootstrap_error>(err).ec
|
|
254
|
-
: std::get<std::error_code>(err);
|
|
255
|
-
if (ec) {
|
|
254
|
+
cmd->start(
|
|
255
|
+
[start = std::chrono::steady_clock::now(),
|
|
256
|
+
self = shared_from_this(),
|
|
257
|
+
type,
|
|
258
|
+
cmd,
|
|
259
|
+
handler = collector->build_reporter()](operations::http_noop_response&& resp) {
|
|
260
|
+
diag::ping_state state = diag::ping_state::ok;
|
|
261
|
+
std::optional<std::string> error{};
|
|
262
|
+
if (auto ec = resp.ctx.ec; ec) {
|
|
256
263
|
if (ec == errc::common::unambiguous_timeout ||
|
|
257
264
|
ec == errc::common::ambiguous_timeout) {
|
|
258
265
|
state = diag::ping_state::timeout;
|
|
259
266
|
} else {
|
|
260
267
|
state = diag::ping_state::error;
|
|
261
268
|
}
|
|
262
|
-
error.emplace(fmt::format(
|
|
263
|
-
|
|
269
|
+
error.emplace(fmt::format("code={}, message={}, http_code={}",
|
|
270
|
+
ec.value(),
|
|
271
|
+
ec.message(),
|
|
272
|
+
resp.ctx.http_status));
|
|
264
273
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if (ec) {
|
|
272
|
-
if (ec == errc::common::unambiguous_timeout ||
|
|
273
|
-
ec == errc::common::ambiguous_timeout) {
|
|
274
|
-
state = diag::ping_state::timeout;
|
|
275
|
-
} else {
|
|
276
|
-
state = diag::ping_state::error;
|
|
274
|
+
auto remote_address = cmd->session_->remote_address();
|
|
275
|
+
// If not connected, the remote address will be empty. Better to
|
|
276
|
+
// give the user some context on the "attempted" remote address.
|
|
277
|
+
if (remote_address.empty()) {
|
|
278
|
+
remote_address =
|
|
279
|
+
fmt::format("{}:{}", cmd->session_->hostname(), cmd->session_->port());
|
|
277
280
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
diag::endpoint_ping_info{ type,
|
|
291
|
-
cmd->session_->id(),
|
|
292
|
-
std::chrono::duration_cast<std::chrono::microseconds>(
|
|
293
|
-
std::chrono::steady_clock::now() - start),
|
|
294
|
-
remote_address,
|
|
295
|
-
cmd->session_->local_address(),
|
|
296
|
-
state,
|
|
297
|
-
{},
|
|
298
|
-
error });
|
|
299
|
-
self->check_in(type, cmd->session_);
|
|
300
|
-
});
|
|
281
|
+
handler->report(
|
|
282
|
+
diag::endpoint_ping_info{ type,
|
|
283
|
+
cmd->session_->id(),
|
|
284
|
+
std::chrono::duration_cast<std::chrono::microseconds>(
|
|
285
|
+
std::chrono::steady_clock::now() - start),
|
|
286
|
+
remote_address,
|
|
287
|
+
cmd->session_->local_address(),
|
|
288
|
+
state,
|
|
289
|
+
{},
|
|
290
|
+
error });
|
|
291
|
+
self->check_in(type, cmd->session_);
|
|
292
|
+
});
|
|
301
293
|
|
|
302
294
|
cmd->set_command_session(session);
|
|
303
295
|
if (!session->is_connected()) {
|
|
@@ -310,19 +302,34 @@ public:
|
|
|
310
302
|
}
|
|
311
303
|
}
|
|
312
304
|
|
|
305
|
+
struct node_details {
|
|
306
|
+
std::string hostname{};
|
|
307
|
+
std::uint16_t port{};
|
|
308
|
+
std::string node_uuid{};
|
|
309
|
+
std::string canonical_hostname{};
|
|
310
|
+
std::uint16_t canonical_port{};
|
|
311
|
+
};
|
|
312
|
+
|
|
313
313
|
auto check_out(service_type type,
|
|
314
|
-
|
|
315
|
-
std::string
|
|
316
|
-
const std::string& undesired_node = {})
|
|
314
|
+
std::string preferred_node_address,
|
|
315
|
+
const std::string& undesired_node_address = {})
|
|
317
316
|
-> std::pair<std::error_code, std::shared_ptr<http_session>>
|
|
318
317
|
{
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
if (
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
318
|
+
node_details preferred_node{};
|
|
319
|
+
|
|
320
|
+
if (preferred_node_address.empty() && !undesired_node_address.empty()) {
|
|
321
|
+
// This is currently only used by Columnar to avoid the node
|
|
322
|
+
// that was last used and to satisfy the requirement for retrying on a different randomly
|
|
323
|
+
// selected node (as opposed to any node we have an idle session to).
|
|
324
|
+
if (auto n = pick_random_node(type, undesired_node_address); n.port != 0) {
|
|
325
|
+
preferred_node_address = fmt::format("{}:{}", n.hostname, n.port);
|
|
326
|
+
preferred_node = std::move(n);
|
|
327
|
+
}
|
|
328
|
+
} else if (!preferred_node_address.empty()) {
|
|
329
|
+
// A 'sticky' node was specified. We should populate the node details.
|
|
330
|
+
preferred_node = lookup_node(type, preferred_node_address);
|
|
331
|
+
if (preferred_node.port == 0) {
|
|
332
|
+
return { errc::common::service_not_available, nullptr };
|
|
326
333
|
}
|
|
327
334
|
}
|
|
328
335
|
|
|
@@ -338,21 +345,21 @@ public:
|
|
|
338
345
|
});
|
|
339
346
|
std::shared_ptr<http_session> session{};
|
|
340
347
|
while (!idle_sessions_[type].empty()) {
|
|
341
|
-
if (
|
|
348
|
+
if (preferred_node_address.empty()) {
|
|
342
349
|
session = idle_sessions_[type].front();
|
|
343
350
|
idle_sessions_[type].pop_front();
|
|
344
351
|
if (session->reset_idle()) {
|
|
345
352
|
break;
|
|
346
353
|
}
|
|
347
354
|
} else {
|
|
348
|
-
auto [hostname, port] = split_host_port(preferred_node);
|
|
349
|
-
|
|
350
355
|
auto ptr = std::find_if(idle_sessions_[type].begin(),
|
|
351
356
|
idle_sessions_[type].end(),
|
|
352
|
-
[&
|
|
357
|
+
[&preferred_node_address,
|
|
358
|
+
&h = preferred_node.hostname,
|
|
359
|
+
&p = preferred_node.port](const auto& s) {
|
|
353
360
|
// Check for a match using both the unresolved hostname & IP
|
|
354
361
|
// address
|
|
355
|
-
return (s->remote_address() ==
|
|
362
|
+
return (s->remote_address() == preferred_node_address ||
|
|
356
363
|
(s->hostname() == h && s->port() == std::to_string(p)));
|
|
357
364
|
});
|
|
358
365
|
if (ptr != idle_sessions_[type].end()) {
|
|
@@ -362,7 +369,7 @@ public:
|
|
|
362
369
|
break;
|
|
363
370
|
}
|
|
364
371
|
} else {
|
|
365
|
-
session = create_session(type,
|
|
372
|
+
session = create_session(type, preferred_node);
|
|
366
373
|
break;
|
|
367
374
|
}
|
|
368
375
|
}
|
|
@@ -374,12 +381,12 @@ public:
|
|
|
374
381
|
session.reset();
|
|
375
382
|
}
|
|
376
383
|
if (!session) {
|
|
377
|
-
auto
|
|
378
|
-
|
|
379
|
-
if (port == 0) {
|
|
384
|
+
auto node = preferred_node_address.empty() ? next_node(type)
|
|
385
|
+
: lookup_node(type, preferred_node_address);
|
|
386
|
+
if (node.port == 0) {
|
|
380
387
|
return { errc::common::service_not_available, nullptr };
|
|
381
388
|
}
|
|
382
|
-
session = create_session(type,
|
|
389
|
+
session = create_session(type, node);
|
|
383
390
|
}
|
|
384
391
|
if (session->is_connected()) {
|
|
385
392
|
busy_sessions_[type].push_back(session);
|
|
@@ -395,9 +402,20 @@ public:
|
|
|
395
402
|
return;
|
|
396
403
|
}
|
|
397
404
|
if (!session->is_connected()) {
|
|
398
|
-
|
|
399
|
-
|
|
405
|
+
{
|
|
406
|
+
std::scoped_lock lock(sessions_mutex_);
|
|
407
|
+
if (auto pend_it = pending_sessions_.find(type); pend_it != pending_sessions_.end()) {
|
|
408
|
+
pend_it->second.remove_if([id = session->id()](const auto& s) {
|
|
409
|
+
return !s || s->id() == id;
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
CB_LOG_DEBUG("{} HTTP session never connected. Ensured session is not in pending.",
|
|
414
|
+
session->log_prefix());
|
|
415
|
+
return;
|
|
400
416
|
}
|
|
417
|
+
bool should_stop = false;
|
|
418
|
+
std::chrono::milliseconds idle_timeout{};
|
|
401
419
|
{
|
|
402
420
|
std::scoped_lock lock(config_mutex_);
|
|
403
421
|
if (!session->keep_alive() || !config_.has_node(options_.network,
|
|
@@ -405,22 +423,34 @@ public:
|
|
|
405
423
|
options_.enable_tls,
|
|
406
424
|
session->hostname(),
|
|
407
425
|
session->port())) {
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
426
|
+
should_stop = true;
|
|
427
|
+
} else {
|
|
428
|
+
idle_timeout = options_.idle_http_connection_timeout;
|
|
411
429
|
}
|
|
412
430
|
}
|
|
431
|
+
if (should_stop) {
|
|
432
|
+
return asio::post(session->get_executor(), [session]() {
|
|
433
|
+
session->stop();
|
|
434
|
+
});
|
|
435
|
+
}
|
|
413
436
|
if (!session->is_stopped()) {
|
|
414
|
-
|
|
437
|
+
// set_idle() arms the idle timer via async_wait — it never calls stop() inline,
|
|
438
|
+
// so on_stop cannot re-enter sessions_mutex_ here. It must precede publication to
|
|
439
|
+
// idle_sessions_ so a concurrent check_out's reset_idle() finds a pending timer.
|
|
440
|
+
session->set_idle(idle_timeout);
|
|
415
441
|
CB_LOG_DEBUG("{} put HTTP session back to idle connections", session->log_prefix());
|
|
416
442
|
std::scoped_lock lock(sessions_mutex_);
|
|
417
443
|
idle_sessions_[type].push_back(session);
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
444
|
+
if (auto busy_it = busy_sessions_.find(type); busy_it != busy_sessions_.end()) {
|
|
445
|
+
busy_it->second.remove_if([id = session->id()](const auto& s) -> bool {
|
|
446
|
+
return !s || s->id() == id;
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
if (auto pend_it = pending_sessions_.find(type); pend_it != pending_sessions_.end()) {
|
|
450
|
+
pend_it->second.remove_if([id = session->id()](const auto& s) -> bool {
|
|
451
|
+
return !s || s->id() == id;
|
|
452
|
+
});
|
|
453
|
+
}
|
|
424
454
|
}
|
|
425
455
|
}
|
|
426
456
|
|
|
@@ -462,13 +492,11 @@ public:
|
|
|
462
492
|
}
|
|
463
493
|
|
|
464
494
|
template<typename Request, typename Handler>
|
|
465
|
-
void execute(Request request,
|
|
466
|
-
Handler&& handler,
|
|
467
|
-
const couchbase::core::cluster_credentials& credentials)
|
|
495
|
+
void execute(Request request, Handler&& handler)
|
|
468
496
|
{
|
|
469
497
|
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
470
498
|
if (!configured_) {
|
|
471
|
-
return defer_command(request, std::move(handler)
|
|
499
|
+
return defer_command(request, std::move(handler));
|
|
472
500
|
}
|
|
473
501
|
#endif
|
|
474
502
|
std::string preferred_node;
|
|
@@ -477,12 +505,12 @@ public:
|
|
|
477
505
|
preferred_node = *request.send_to_node;
|
|
478
506
|
}
|
|
479
507
|
}
|
|
480
|
-
auto [error, session] = check_out(request.type,
|
|
508
|
+
auto [error, session] = check_out(request.type, preferred_node);
|
|
481
509
|
if (error) {
|
|
482
510
|
typename Request::error_context_type ctx{};
|
|
483
511
|
ctx.ec = error;
|
|
484
|
-
using
|
|
485
|
-
return handler(request.make_response(std::move(ctx),
|
|
512
|
+
using encoded_response_type = typename Request::encoded_response_type;
|
|
513
|
+
return handler(request.make_response(std::move(ctx), encoded_response_type{}));
|
|
486
514
|
}
|
|
487
515
|
|
|
488
516
|
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
@@ -494,8 +522,6 @@ public:
|
|
|
494
522
|
app_telemetry_meter_,
|
|
495
523
|
options_.default_timeout_for(request.type),
|
|
496
524
|
dispatch_timeout_);
|
|
497
|
-
cmd->start([self = shared_from_this(), cmd, handler = std::forward<Handler>(handler)](
|
|
498
|
-
error_union err, io::http_response&& msg) mutable {
|
|
499
525
|
#else
|
|
500
526
|
auto cmd = std::make_shared<operations::http_command<Request>>(
|
|
501
527
|
ctx_,
|
|
@@ -504,42 +530,12 @@ public:
|
|
|
504
530
|
meter_,
|
|
505
531
|
app_telemetry_meter_,
|
|
506
532
|
options_.default_timeout_for(request.type));
|
|
507
|
-
cmd->start([self = shared_from_this(), cmd, handler = std::forward<Handler>(handler)](
|
|
508
|
-
std::error_code ec, io::http_response&& msg) mutable {
|
|
509
|
-
#endif
|
|
510
|
-
using command_type = typename decltype(cmd)::element_type;
|
|
511
|
-
using encoded_response_type = typename command_type::encoded_response_type;
|
|
512
|
-
using error_context_type = typename command_type::error_context_type;
|
|
513
|
-
encoded_response_type resp{ std::move(msg) };
|
|
514
|
-
error_context_type ctx{};
|
|
515
|
-
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
516
|
-
if (!std::holds_alternative<std::monostate>(err)) {
|
|
517
|
-
if (std::holds_alternative<impl::bootstrap_error>(err)) {
|
|
518
|
-
auto bootstrap_error = std::get<impl::bootstrap_error>(err);
|
|
519
|
-
if (bootstrap_error.ec == errc::common::unambiguous_timeout) {
|
|
520
|
-
CB_LOG_DEBUG("Timeout caused by bootstrap error. code={}, ec_message={}, message={}.",
|
|
521
|
-
bootstrap_error.ec.value(),
|
|
522
|
-
bootstrap_error.ec.message(),
|
|
523
|
-
bootstrap_error.error_message);
|
|
524
|
-
}
|
|
525
|
-
ctx.ec = bootstrap_error.ec;
|
|
526
|
-
} else {
|
|
527
|
-
ctx.ec = std::get<std::error_code>(err);
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
#else
|
|
531
|
-
ctx.ec = ec;
|
|
532
533
|
#endif
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
ctx.last_dispatched_from = cmd->session_->local_address();
|
|
539
|
-
ctx.last_dispatched_to = cmd->session_->remote_address();
|
|
540
|
-
ctx.hostname = cmd->session_->http_context().hostname;
|
|
541
|
-
ctx.port = cmd->session_->http_context().port;
|
|
542
|
-
handler(cmd->request.make_response(std::move(ctx), std::move(resp)));
|
|
534
|
+
|
|
535
|
+
using response_type = typename Request::response_type;
|
|
536
|
+
cmd->start([self = shared_from_this(), cmd, handler = std::forward<Handler>(handler)](
|
|
537
|
+
response_type&& resp) mutable {
|
|
538
|
+
handler(std::move(resp));
|
|
543
539
|
self->check_in(cmd->request.type, cmd->session_);
|
|
544
540
|
});
|
|
545
541
|
cmd->set_command_session(session);
|
|
@@ -596,15 +592,14 @@ public:
|
|
|
596
592
|
|
|
597
593
|
// stop this session and create a new one w/ new hostname + port
|
|
598
594
|
session->stop();
|
|
599
|
-
auto
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
if (port == 0) {
|
|
595
|
+
const auto node = preferred_node.empty()
|
|
596
|
+
? self->next_node(session->type())
|
|
597
|
+
: self->lookup_node(session->type(), preferred_node);
|
|
598
|
+
if (node.port == 0) {
|
|
603
599
|
cb(errc::common::service_not_available, {});
|
|
604
600
|
return;
|
|
605
601
|
}
|
|
606
|
-
auto new_session =
|
|
607
|
-
self->create_session(session->type(), session->credentials(), hostname, port, node_uuid);
|
|
602
|
+
auto new_session = self->create_session(session->type(), node);
|
|
608
603
|
if (new_session->is_connected()) {
|
|
609
604
|
{
|
|
610
605
|
const std::scoped_lock inner_lock(self->sessions_mutex_);
|
|
@@ -704,15 +699,14 @@ private:
|
|
|
704
699
|
}
|
|
705
700
|
// stop this session and create a new one w/ new hostname + port
|
|
706
701
|
session->stop();
|
|
707
|
-
auto
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
if (port == 0) {
|
|
702
|
+
const auto node = preferred_node.empty()
|
|
703
|
+
? self->next_node(session->type())
|
|
704
|
+
: self->lookup_node(session->type(), preferred_node);
|
|
705
|
+
if (node.port == 0) {
|
|
711
706
|
cmd->invoke_handler(errc::common::service_not_available, {});
|
|
712
707
|
return;
|
|
713
708
|
}
|
|
714
|
-
auto new_session =
|
|
715
|
-
self->create_session(session->type(), session->credentials(), hostname, port, node_uuid);
|
|
709
|
+
auto new_session = self->create_session(session->type(), node);
|
|
716
710
|
cmd->set_command_session(new_session);
|
|
717
711
|
if (new_session->is_connected()) {
|
|
718
712
|
std::scoped_lock inner_lock(self->sessions_mutex_);
|
|
@@ -729,53 +723,78 @@ private:
|
|
|
729
723
|
});
|
|
730
724
|
}
|
|
731
725
|
|
|
732
|
-
auto create_session(service_type type,
|
|
733
|
-
const couchbase::core::cluster_credentials& credentials,
|
|
734
|
-
const std::string& hostname,
|
|
735
|
-
std::uint16_t port,
|
|
736
|
-
const std::string& node_uuid) -> std::shared_ptr<http_session>
|
|
726
|
+
auto create_session(service_type type, const node_details& node) -> std::shared_ptr<http_session>
|
|
737
727
|
{
|
|
738
728
|
std::shared_ptr<http_session> session;
|
|
739
729
|
if (options_.enable_tls) {
|
|
740
|
-
session = std::make_shared<http_session>(
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
730
|
+
session = std::make_shared<http_session>(type,
|
|
731
|
+
client_id_,
|
|
732
|
+
node.node_uuid,
|
|
733
|
+
ctx_,
|
|
734
|
+
tls_,
|
|
735
|
+
origin_,
|
|
736
|
+
node.hostname,
|
|
737
|
+
std::to_string(node.port),
|
|
738
|
+
http_context{
|
|
739
|
+
config_,
|
|
740
|
+
options_,
|
|
741
|
+
query_cache_,
|
|
742
|
+
node.hostname,
|
|
743
|
+
node.port,
|
|
744
|
+
node.canonical_hostname,
|
|
745
|
+
node.canonical_port,
|
|
746
|
+
});
|
|
750
747
|
} else {
|
|
751
|
-
session = std::make_shared<http_session>(
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
748
|
+
session = std::make_shared<http_session>(type,
|
|
749
|
+
client_id_,
|
|
750
|
+
node.node_uuid,
|
|
751
|
+
ctx_,
|
|
752
|
+
origin_,
|
|
753
|
+
node.hostname,
|
|
754
|
+
std::to_string(node.port),
|
|
755
|
+
http_context{
|
|
756
|
+
config_,
|
|
757
|
+
options_,
|
|
758
|
+
query_cache_,
|
|
759
|
+
node.hostname,
|
|
760
|
+
node.port,
|
|
761
|
+
node.canonical_hostname,
|
|
762
|
+
node.canonical_port,
|
|
763
|
+
});
|
|
760
764
|
}
|
|
761
765
|
|
|
762
766
|
session->on_stop([type, id = session->id(), self = this->shared_from_this()]() {
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
767
|
+
// Declared outside the lock so destructors run after sessions_mutex_ is released.
|
|
768
|
+
// cppcheck-suppress variableScope
|
|
769
|
+
std::vector<std::shared_ptr<http_session>> dropped;
|
|
770
|
+
{
|
|
771
|
+
const std::scoped_lock inner_lock(self->sessions_mutex_);
|
|
772
|
+
for (auto* map :
|
|
773
|
+
{ &self->busy_sessions_, &self->idle_sessions_, &self->pending_sessions_ }) {
|
|
774
|
+
auto map_it = map->find(type);
|
|
775
|
+
if (map_it == map->end()) {
|
|
776
|
+
continue;
|
|
777
|
+
}
|
|
778
|
+
auto& list = map_it->second;
|
|
779
|
+
for (auto it = list.begin(); it != list.end();) {
|
|
780
|
+
if (!*it || (*it)->id() == id) {
|
|
781
|
+
if (*it) {
|
|
782
|
+
dropped.push_back(std::move(*it));
|
|
783
|
+
}
|
|
784
|
+
it = list.erase(it);
|
|
785
|
+
} else {
|
|
786
|
+
++it;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
}
|
|
770
791
|
});
|
|
771
792
|
return session;
|
|
772
793
|
}
|
|
773
794
|
|
|
774
795
|
#ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
|
|
775
796
|
template<typename Request, typename Handler>
|
|
776
|
-
void defer_command(Request request,
|
|
777
|
-
Handler&& handler,
|
|
778
|
-
const couchbase::core::cluster_credentials& credentials)
|
|
797
|
+
void defer_command(Request request, Handler&& handler)
|
|
779
798
|
{
|
|
780
799
|
{
|
|
781
800
|
std::scoped_lock bootstrap_error_lock(last_bootstrap_error_mutex_);
|
|
@@ -794,74 +813,44 @@ private:
|
|
|
794
813
|
app_telemetry_meter_,
|
|
795
814
|
options_.default_timeout_for(request.type),
|
|
796
815
|
dispatch_timeout_);
|
|
816
|
+
using response_type = typename Request::response_type;
|
|
797
817
|
cmd->start([self = shared_from_this(), cmd, handler = std::forward<Handler>(handler)](
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
using encoded_response_type = typename command_type::encoded_response_type;
|
|
801
|
-
using error_context_type = typename command_type::error_context_type;
|
|
802
|
-
encoded_response_type resp{ std::move(msg) };
|
|
803
|
-
error_context_type ctx{};
|
|
804
|
-
if (!std::holds_alternative<std::monostate>(err)) {
|
|
805
|
-
if (std::holds_alternative<impl::bootstrap_error>(err)) {
|
|
806
|
-
auto bootstrap_error = std::get<impl::bootstrap_error>(err);
|
|
807
|
-
if (bootstrap_error.ec == errc::common::unambiguous_timeout) {
|
|
808
|
-
CB_LOG_DEBUG("Timeout caused by bootstrap error. code={}, ec_message={}, message={}.",
|
|
809
|
-
bootstrap_error.ec.value(),
|
|
810
|
-
bootstrap_error.ec.message(),
|
|
811
|
-
bootstrap_error.error_message);
|
|
812
|
-
}
|
|
813
|
-
ctx.ec = bootstrap_error.ec;
|
|
814
|
-
} else {
|
|
815
|
-
ctx.ec = std::get<std::error_code>(err);
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
ctx.client_context_id = cmd->client_context_id_;
|
|
819
|
-
ctx.method = cmd->encoded.method;
|
|
820
|
-
ctx.path = cmd->encoded.path;
|
|
821
|
-
ctx.http_status = resp.status_code;
|
|
822
|
-
ctx.http_body = resp.body.data();
|
|
823
|
-
if (cmd->session_) {
|
|
824
|
-
ctx.last_dispatched_from = cmd->session_->local_address();
|
|
825
|
-
ctx.last_dispatched_to = cmd->session_->remote_address();
|
|
826
|
-
ctx.hostname = cmd->session_->http_context().hostname;
|
|
827
|
-
ctx.port = cmd->session_->http_context().port;
|
|
828
|
-
}
|
|
829
|
-
handler(cmd->request.make_response(std::move(ctx), std::move(resp)));
|
|
818
|
+
response_type&& resp) mutable {
|
|
819
|
+
handler(std::move(resp));
|
|
830
820
|
self->check_in(cmd->request.type, cmd->session_);
|
|
831
821
|
});
|
|
832
822
|
CB_LOG_DEBUG(R"(Adding HTTP request to deferred queue: {}, client_context_id="{}")",
|
|
833
823
|
cmd->request.type,
|
|
834
824
|
cmd->client_context_id_);
|
|
835
|
-
add_to_deferred_queue(
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
}
|
|
825
|
+
add_to_deferred_queue([self = shared_from_this(), cmd, request](error_union err) mutable {
|
|
826
|
+
if (!std::holds_alternative<std::monostate>(err)) {
|
|
827
|
+
using response_type = typename Request::encoded_response_type;
|
|
828
|
+
return cmd->invoke_handler(err, response_type{});
|
|
829
|
+
}
|
|
841
830
|
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
}
|
|
852
|
-
}
|
|
853
|
-
auto [error, session] = self->check_out(request.type, credentials, preferred_node);
|
|
854
|
-
if (error) {
|
|
855
|
-
using response_type = typename Request::encoded_response_type;
|
|
856
|
-
return cmd->invoke_handler(error, response_type{});
|
|
857
|
-
}
|
|
858
|
-
cmd->set_command_session(session);
|
|
859
|
-
if (!session->is_connected()) {
|
|
860
|
-
self->connect_then_send(session, cmd, preferred_node);
|
|
861
|
-
} else {
|
|
862
|
-
cmd->send_to();
|
|
831
|
+
// don't do anything if the command wasn't dispatched or has already timed out
|
|
832
|
+
auto now = std::chrono::steady_clock::now();
|
|
833
|
+
if (cmd->dispatch_deadline_expiry() < now || cmd->deadline_expiry() < now) {
|
|
834
|
+
return;
|
|
835
|
+
}
|
|
836
|
+
std::string preferred_node;
|
|
837
|
+
if constexpr (http_traits::supports_sticky_node_v<Request>) {
|
|
838
|
+
if (request.send_to_node) {
|
|
839
|
+
preferred_node = *request.send_to_node;
|
|
863
840
|
}
|
|
864
|
-
}
|
|
841
|
+
}
|
|
842
|
+
auto [error, session] = self->check_out(request.type, preferred_node);
|
|
843
|
+
if (error) {
|
|
844
|
+
using response_type = typename Request::encoded_response_type;
|
|
845
|
+
return cmd->invoke_handler(error, response_type{});
|
|
846
|
+
}
|
|
847
|
+
cmd->set_command_session(session);
|
|
848
|
+
if (!session->is_connected()) {
|
|
849
|
+
self->connect_then_send(session, cmd, preferred_node);
|
|
850
|
+
} else {
|
|
851
|
+
cmd->send_to();
|
|
852
|
+
}
|
|
853
|
+
});
|
|
865
854
|
}
|
|
866
855
|
|
|
867
856
|
void drain_deferred_queue(error_union err)
|
|
@@ -881,34 +870,29 @@ private:
|
|
|
881
870
|
}
|
|
882
871
|
#endif
|
|
883
872
|
|
|
884
|
-
auto next_node(service_type type) ->
|
|
873
|
+
auto next_node(service_type type) -> node_details
|
|
885
874
|
{
|
|
886
875
|
std::scoped_lock lock(config_mutex_);
|
|
887
876
|
auto candidates = config_.nodes.size();
|
|
888
877
|
while (candidates > 0) {
|
|
889
878
|
--candidates;
|
|
890
|
-
std::scoped_lock index_lock(next_index_mutex_);
|
|
879
|
+
const std::scoped_lock index_lock(next_index_mutex_);
|
|
891
880
|
const auto& node = config_.nodes[next_index_];
|
|
892
881
|
next_index_ = (next_index_ + 1) % config_.nodes.size();
|
|
893
|
-
std::uint16_t port = node.port_or(options_.network, type, options_.enable_tls, 0);
|
|
882
|
+
const std::uint16_t port = node.port_or(options_.network, type, options_.enable_tls, 0);
|
|
894
883
|
if (port != 0) {
|
|
895
884
|
return {
|
|
896
|
-
node.hostname_for(options_.network),
|
|
897
|
-
|
|
898
|
-
node.node_uuid,
|
|
885
|
+
node.hostname_for(options_.network), port, node.node_uuid, node.hostname,
|
|
886
|
+
node.port_or(type, options_.enable_tls, 0),
|
|
899
887
|
};
|
|
900
888
|
}
|
|
901
889
|
}
|
|
902
|
-
return {
|
|
903
|
-
"",
|
|
904
|
-
static_cast<std::uint16_t>(0U),
|
|
905
|
-
"",
|
|
906
|
-
};
|
|
890
|
+
return {};
|
|
907
891
|
}
|
|
908
892
|
|
|
909
893
|
auto split_host_port(const std::string& address) -> std::pair<std::string, std::uint16_t>
|
|
910
894
|
{
|
|
911
|
-
auto last_colon = address.find_last_of(':');
|
|
895
|
+
const auto last_colon = address.find_last_of(':');
|
|
912
896
|
if (last_colon == std::string::npos || address.size() - 1 == last_colon) {
|
|
913
897
|
return { "", static_cast<std::uint16_t>(0U) };
|
|
914
898
|
}
|
|
@@ -917,30 +901,22 @@ private:
|
|
|
917
901
|
return { hostname, port };
|
|
918
902
|
}
|
|
919
903
|
|
|
920
|
-
auto lookup_node(service_type type, const std::string&
|
|
921
|
-
-> std::tuple<std::string, std::uint16_t, std::string>
|
|
904
|
+
auto lookup_node(service_type type, const std::string& preferred_node_address) -> node_details
|
|
922
905
|
{
|
|
923
|
-
std::scoped_lock lock(config_mutex_);
|
|
924
|
-
auto [hostname, port] = split_host_port(
|
|
906
|
+
const std::scoped_lock lock(config_mutex_);
|
|
907
|
+
auto [hostname, port] = split_host_port(preferred_node_address);
|
|
925
908
|
for (const auto& node : config_.nodes) {
|
|
926
909
|
if (node.hostname_for(options_.network) == hostname &&
|
|
927
910
|
node.port_or(options_.network, type, options_.enable_tls, 0) == port) {
|
|
928
911
|
return {
|
|
929
|
-
hostname,
|
|
930
|
-
port,
|
|
931
|
-
node.node_uuid,
|
|
912
|
+
hostname, port, node.node_uuid, node.hostname, node.port_or(type, options_.enable_tls, 0),
|
|
932
913
|
};
|
|
933
914
|
}
|
|
934
915
|
}
|
|
935
|
-
return {
|
|
936
|
-
"",
|
|
937
|
-
static_cast<std::uint16_t>(0U),
|
|
938
|
-
"",
|
|
939
|
-
};
|
|
916
|
+
return {};
|
|
940
917
|
}
|
|
941
918
|
|
|
942
|
-
auto pick_random_node(service_type type, const std::string& undesired_node)
|
|
943
|
-
-> std::tuple<std::string, std::uint16_t, std::string>
|
|
919
|
+
auto pick_random_node(service_type type, const std::string& undesired_node) -> node_details
|
|
944
920
|
{
|
|
945
921
|
std::vector<topology::configuration::node> candidate_nodes{};
|
|
946
922
|
{
|
|
@@ -956,11 +932,7 @@ private:
|
|
|
956
932
|
|
|
957
933
|
if (candidate_nodes.empty()) {
|
|
958
934
|
// Could not find any other nodes
|
|
959
|
-
return {
|
|
960
|
-
"",
|
|
961
|
-
static_cast<std::uint16_t>(0U),
|
|
962
|
-
"",
|
|
963
|
-
};
|
|
935
|
+
return {};
|
|
964
936
|
}
|
|
965
937
|
|
|
966
938
|
std::vector<topology::configuration::node> selected{};
|
|
@@ -974,12 +946,15 @@ private:
|
|
|
974
946
|
first_selected.hostname_for(options_.network),
|
|
975
947
|
first_selected.port_or(options_.network, type, options_.enable_tls, 0),
|
|
976
948
|
first_selected.node_uuid,
|
|
949
|
+
first_selected.hostname,
|
|
950
|
+
first_selected.port_or(type, options_.enable_tls, 0),
|
|
977
951
|
};
|
|
978
952
|
}
|
|
979
953
|
|
|
980
954
|
std::string client_id_;
|
|
981
955
|
asio::io_context& ctx_;
|
|
982
|
-
|
|
956
|
+
tls_context_provider& tls_;
|
|
957
|
+
origin& origin_;
|
|
983
958
|
std::shared_ptr<tracing::tracer_wrapper> tracer_{ nullptr };
|
|
984
959
|
std::shared_ptr<metrics::meter_wrapper> meter_{ nullptr };
|
|
985
960
|
std::shared_ptr<core::app_telemetry_meter> app_telemetry_meter_{ nullptr };
|