couchbase 3.7.0 → 3.8.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 +3 -3
- data/ext/CMakeLists.txt +4 -1
- data/ext/cache/extconf_include.rb +4 -3
- data/ext/cache/mozilla-ca-bundle.crt +66 -93
- data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
- data/ext/couchbase/CMakeLists.txt +24 -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/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 +134 -58
- data/ext/couchbase/core/impl/bucket_manager.cxx +87 -35
- data/ext/couchbase/core/impl/collection.cxx +560 -245
- 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 +20 -13
- 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/lookup_in_replica.hxx +1 -1
- 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 +163 -228
- 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 +77 -27
- 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.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 +46 -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.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.hxx +2 -0
- data/ext/couchbase/core/operations/management/collection_drop.hxx +2 -0
- 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 +4 -1
- 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.hxx +2 -0
- 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.hxx +2 -0
- 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/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/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 +60 -15
- 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/password_authenticator.hxx +1 -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 +587 -294
- data/ext/rcb_hdr_histogram.cxx +219 -0
- data/ext/rcb_hdr_histogram.hxx +28 -0
- 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 +81 -50
- data/lib/couchbase/datastructures/couchbase_map.rb +86 -50
- data/lib/couchbase/datastructures/couchbase_queue.rb +64 -38
- data/lib/couchbase/datastructures/couchbase_set.rb +57 -41
- data/lib/couchbase/deprecations.rb +1 -1
- data/lib/couchbase/diagnostics.rb +8 -8
- data/lib/couchbase/errors.rb +6 -0
- 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 +69 -3
- data/lib/couchbase/protostellar/cluster.rb +3 -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 +257 -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 +58 -6
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2025-Present Couchbase, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include "rcb_hdr_histogram.hxx"
|
|
19
|
+
#include "rcb_exceptions.hxx"
|
|
20
|
+
|
|
21
|
+
#include <hdr/hdr_histogram.h>
|
|
22
|
+
#include <ruby.h>
|
|
23
|
+
|
|
24
|
+
#include <mutex>
|
|
25
|
+
#include <shared_mutex>
|
|
26
|
+
#include <vector>
|
|
27
|
+
|
|
28
|
+
namespace couchbase::ruby
|
|
29
|
+
{
|
|
30
|
+
namespace
|
|
31
|
+
{
|
|
32
|
+
struct cb_hdr_histogram_data {
|
|
33
|
+
hdr_histogram* histogram{ nullptr };
|
|
34
|
+
std::shared_mutex mutex{};
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
void
|
|
38
|
+
cb_hdr_histogram_close(cb_hdr_histogram_data* hdr_histogram_data)
|
|
39
|
+
{
|
|
40
|
+
if (hdr_histogram_data->histogram != nullptr) {
|
|
41
|
+
hdr_close(hdr_histogram_data->histogram);
|
|
42
|
+
hdr_histogram_data->histogram = nullptr;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
void
|
|
47
|
+
cb_HdrHistogramC_mark(void* /* ptr */)
|
|
48
|
+
{
|
|
49
|
+
/* no embedded ruby objects -- no mark */
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
void
|
|
53
|
+
cb_HdrHistogramC_free(void* ptr)
|
|
54
|
+
{
|
|
55
|
+
auto* hdr_histogram_data = static_cast<cb_hdr_histogram_data*>(ptr);
|
|
56
|
+
cb_hdr_histogram_close(hdr_histogram_data);
|
|
57
|
+
hdr_histogram_data->~cb_hdr_histogram_data();
|
|
58
|
+
ruby_xfree(hdr_histogram_data);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
std::size_t
|
|
62
|
+
cb_HdrHistogramC_memsize(const void* ptr)
|
|
63
|
+
{
|
|
64
|
+
const auto* hdr_histogram_data = static_cast<const cb_hdr_histogram_data*>(ptr);
|
|
65
|
+
return sizeof(*hdr_histogram_data);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const rb_data_type_t cb_hdr_histogram_type{
|
|
69
|
+
"Couchbase/Utils/HdrHistogramC",
|
|
70
|
+
{
|
|
71
|
+
cb_HdrHistogramC_mark,
|
|
72
|
+
cb_HdrHistogramC_free,
|
|
73
|
+
cb_HdrHistogramC_memsize,
|
|
74
|
+
// only one reserved field when GC.compact implemented
|
|
75
|
+
#ifdef T_MOVED
|
|
76
|
+
nullptr,
|
|
77
|
+
#endif
|
|
78
|
+
{},
|
|
79
|
+
},
|
|
80
|
+
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
|
81
|
+
nullptr,
|
|
82
|
+
nullptr,
|
|
83
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
|
84
|
+
#endif
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
VALUE
|
|
88
|
+
cb_HdrHistogramC_allocate(VALUE klass)
|
|
89
|
+
{
|
|
90
|
+
cb_hdr_histogram_data* hdr_histogram = nullptr;
|
|
91
|
+
VALUE obj =
|
|
92
|
+
TypedData_Make_Struct(klass, cb_hdr_histogram_data, &cb_hdr_histogram_type, hdr_histogram);
|
|
93
|
+
new (hdr_histogram) cb_hdr_histogram_data();
|
|
94
|
+
return obj;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
VALUE
|
|
98
|
+
cb_HdrHistogramC_initialize(VALUE self,
|
|
99
|
+
VALUE lowest_discernible_value,
|
|
100
|
+
VALUE highest_trackable_value,
|
|
101
|
+
VALUE significant_figures)
|
|
102
|
+
{
|
|
103
|
+
Check_Type(lowest_discernible_value, T_FIXNUM);
|
|
104
|
+
Check_Type(highest_trackable_value, T_FIXNUM);
|
|
105
|
+
Check_Type(significant_figures, T_FIXNUM);
|
|
106
|
+
|
|
107
|
+
std::int64_t lowest = NUM2LL(lowest_discernible_value);
|
|
108
|
+
std::int64_t highest = NUM2LL(highest_trackable_value);
|
|
109
|
+
int sigfigs = NUM2INT(significant_figures);
|
|
110
|
+
|
|
111
|
+
cb_hdr_histogram_data* hdr_histogram;
|
|
112
|
+
TypedData_Get_Struct(self, cb_hdr_histogram_data, &cb_hdr_histogram_type, hdr_histogram);
|
|
113
|
+
|
|
114
|
+
int res;
|
|
115
|
+
{
|
|
116
|
+
const std::unique_lock lock(hdr_histogram->mutex);
|
|
117
|
+
res = hdr_init(lowest, highest, sigfigs, &hdr_histogram->histogram);
|
|
118
|
+
}
|
|
119
|
+
if (res != 0) {
|
|
120
|
+
rb_raise(exc_couchbase_error(), "failed to initialize HDR histogram");
|
|
121
|
+
return self;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return self;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
VALUE
|
|
128
|
+
cb_HdrHistogramC_close(VALUE self)
|
|
129
|
+
{
|
|
130
|
+
cb_hdr_histogram_data* hdr_histogram;
|
|
131
|
+
TypedData_Get_Struct(self, cb_hdr_histogram_data, &cb_hdr_histogram_type, hdr_histogram);
|
|
132
|
+
{
|
|
133
|
+
const std::unique_lock lock(hdr_histogram->mutex);
|
|
134
|
+
cb_hdr_histogram_close(hdr_histogram);
|
|
135
|
+
}
|
|
136
|
+
return Qnil;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
VALUE
|
|
140
|
+
cb_HdrHistogramC_record_value(VALUE self, VALUE value)
|
|
141
|
+
{
|
|
142
|
+
Check_Type(value, T_FIXNUM);
|
|
143
|
+
|
|
144
|
+
std::int64_t val = NUM2LL(value);
|
|
145
|
+
|
|
146
|
+
cb_hdr_histogram_data* hdr_histogram;
|
|
147
|
+
TypedData_Get_Struct(self, cb_hdr_histogram_data, &cb_hdr_histogram_type, hdr_histogram);
|
|
148
|
+
|
|
149
|
+
{
|
|
150
|
+
const std::shared_lock lock(hdr_histogram->mutex);
|
|
151
|
+
hdr_record_value_atomic(hdr_histogram->histogram, val);
|
|
152
|
+
}
|
|
153
|
+
return Qnil;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
VALUE
|
|
157
|
+
cb_HdrHistogramC_get_percentiles_and_reset(VALUE self, VALUE percentiles)
|
|
158
|
+
{
|
|
159
|
+
Check_Type(percentiles, T_ARRAY);
|
|
160
|
+
|
|
161
|
+
cb_hdr_histogram_data* hdr_histogram;
|
|
162
|
+
TypedData_Get_Struct(self, cb_hdr_histogram_data, &cb_hdr_histogram_type, hdr_histogram);
|
|
163
|
+
|
|
164
|
+
std::vector<std::int64_t> percentile_values{};
|
|
165
|
+
std::int64_t total_count;
|
|
166
|
+
{
|
|
167
|
+
const std::unique_lock lock(hdr_histogram->mutex);
|
|
168
|
+
total_count = hdr_histogram->histogram->total_count;
|
|
169
|
+
for (std::size_t i = 0; i < static_cast<std::size_t>(RARRAY_LEN(percentiles)); ++i) {
|
|
170
|
+
VALUE entry = rb_ary_entry(percentiles, static_cast<long>(i));
|
|
171
|
+
Check_Type(entry, T_FLOAT);
|
|
172
|
+
double perc = NUM2DBL(entry);
|
|
173
|
+
std::int64_t value_at_perc = hdr_value_at_percentile(hdr_histogram->histogram, perc);
|
|
174
|
+
percentile_values.push_back(value_at_perc);
|
|
175
|
+
}
|
|
176
|
+
hdr_reset(hdr_histogram->histogram);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
static const VALUE sym_total_count = rb_id2sym(rb_intern("total_count"));
|
|
180
|
+
static const VALUE sym_percentiles = rb_id2sym(rb_intern("percentiles"));
|
|
181
|
+
VALUE res = rb_hash_new();
|
|
182
|
+
rb_hash_aset(res, sym_total_count, LL2NUM(total_count));
|
|
183
|
+
VALUE perc_array = rb_ary_new_capa(static_cast<long>(percentile_values.size()));
|
|
184
|
+
for (const auto& val : percentile_values) {
|
|
185
|
+
rb_ary_push(perc_array, LL2NUM(val));
|
|
186
|
+
}
|
|
187
|
+
rb_hash_aset(res, sym_percentiles, perc_array);
|
|
188
|
+
return res;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
VALUE
|
|
192
|
+
cb_HdrHistogramC_bin_count(VALUE self)
|
|
193
|
+
{
|
|
194
|
+
cb_hdr_histogram_data* hdr_histogram;
|
|
195
|
+
TypedData_Get_Struct(self, cb_hdr_histogram_data, &cb_hdr_histogram_type, hdr_histogram);
|
|
196
|
+
|
|
197
|
+
std::int32_t bin_count;
|
|
198
|
+
{
|
|
199
|
+
const std::unique_lock lock(hdr_histogram->mutex);
|
|
200
|
+
bin_count = hdr_histogram->histogram->bucket_count;
|
|
201
|
+
}
|
|
202
|
+
return LONG2NUM(bin_count);
|
|
203
|
+
}
|
|
204
|
+
} // namespace
|
|
205
|
+
|
|
206
|
+
void
|
|
207
|
+
init_hdr_histogram(VALUE mCouchbase)
|
|
208
|
+
{
|
|
209
|
+
VALUE mUtils = rb_define_module_under(mCouchbase, "Utils");
|
|
210
|
+
VALUE cHdrHistogramC = rb_define_class_under(mUtils, "HdrHistogramC", rb_cObject);
|
|
211
|
+
rb_define_alloc_func(cHdrHistogramC, cb_HdrHistogramC_allocate);
|
|
212
|
+
rb_define_method(cHdrHistogramC, "initialize", cb_HdrHistogramC_initialize, 3);
|
|
213
|
+
rb_define_method(cHdrHistogramC, "close", cb_HdrHistogramC_close, 0);
|
|
214
|
+
rb_define_method(cHdrHistogramC, "record_value", cb_HdrHistogramC_record_value, 1);
|
|
215
|
+
rb_define_method(cHdrHistogramC, "bin_count", cb_HdrHistogramC_bin_count, 0);
|
|
216
|
+
rb_define_method(
|
|
217
|
+
cHdrHistogramC, "get_percentiles_and_reset", cb_HdrHistogramC_get_percentiles_and_reset, 1);
|
|
218
|
+
}
|
|
219
|
+
} // namespace couchbase::ruby
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2025-Present Couchbase, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#ifndef COUCHBASE_RUBY_RCB_HDR_HISTOGRAM_HXX
|
|
19
|
+
#define COUCHBASE_RUBY_RCB_HDR_HISTOGRAM_HXX
|
|
20
|
+
|
|
21
|
+
#include <ruby/internal/value.h>
|
|
22
|
+
|
|
23
|
+
namespace couchbase::ruby
|
|
24
|
+
{
|
|
25
|
+
void
|
|
26
|
+
init_hdr_histogram(VALUE mCouchbase);
|
|
27
|
+
} // namespace couchbase::ruby
|
|
28
|
+
#endif // COUCHBASE_RUBY_RCB_HDR_HISTOGRAM_HXX
|
data/ext/rcb_multi.cxx
CHANGED
|
@@ -17,7 +17,20 @@
|
|
|
17
17
|
|
|
18
18
|
#include <core/cluster.hxx>
|
|
19
19
|
#include <core/document_id.hxx>
|
|
20
|
+
|
|
21
|
+
// TODO(DC): Compilation fails unless all operations that support legacy durability are included
|
|
22
|
+
// This is probably something we should address in the C++ core. Including them all for now.
|
|
23
|
+
#include <core/operations/document_append.hxx>
|
|
24
|
+
#include <core/operations/document_decrement.hxx>
|
|
20
25
|
#include <core/operations/document_get.hxx>
|
|
26
|
+
#include <core/operations/document_increment.hxx>
|
|
27
|
+
#include <core/operations/document_insert.hxx>
|
|
28
|
+
#include <core/operations/document_mutate_in.hxx>
|
|
29
|
+
#include <core/operations/document_prepend.hxx>
|
|
30
|
+
#include <core/operations/document_remove.hxx>
|
|
31
|
+
#include <core/operations/document_replace.hxx>
|
|
32
|
+
#include <core/operations/document_upsert.hxx>
|
|
33
|
+
|
|
21
34
|
#include <couchbase/cluster.hxx>
|
|
22
35
|
#include <couchbase/upsert_options.hxx>
|
|
23
36
|
|
|
@@ -32,7 +45,6 @@ namespace couchbase::ruby
|
|
|
32
45
|
{
|
|
33
46
|
namespace
|
|
34
47
|
{
|
|
35
|
-
|
|
36
48
|
void
|
|
37
49
|
cb_extract_array_of_ids(std::vector<core::document_id>& ids, VALUE arg)
|
|
38
50
|
{
|
|
@@ -82,21 +94,29 @@ cb_extract_array_of_ids(std::vector<core::document_id>& ids, VALUE arg)
|
|
|
82
94
|
|
|
83
95
|
void
|
|
84
96
|
cb_extract_array_of_id_content(
|
|
85
|
-
std::vector<std::pair<
|
|
86
|
-
VALUE
|
|
97
|
+
std::vector<std::pair<core::document_id, couchbase::codec::encoded_value>>& id_content,
|
|
98
|
+
VALUE bucket_name,
|
|
99
|
+
VALUE scope_name,
|
|
100
|
+
VALUE collection_name,
|
|
101
|
+
VALUE tuples)
|
|
87
102
|
{
|
|
88
|
-
|
|
103
|
+
cb_check_type(bucket_name, T_STRING);
|
|
104
|
+
cb_check_type(scope_name, T_STRING);
|
|
105
|
+
cb_check_type(collection_name, T_STRING);
|
|
106
|
+
|
|
107
|
+
if (TYPE(tuples) != T_ARRAY) {
|
|
89
108
|
throw ruby_exception(
|
|
90
109
|
rb_eArgError,
|
|
91
|
-
rb_sprintf("Type of ID/content tuples must be an Array, but given %+" PRIsVALUE,
|
|
110
|
+
rb_sprintf("Type of ID/content tuples must be an Array, but given %+" PRIsVALUE, tuples));
|
|
92
111
|
}
|
|
93
|
-
|
|
112
|
+
|
|
113
|
+
auto num_of_tuples = static_cast<std::size_t>(RARRAY_LEN(tuples));
|
|
94
114
|
if (num_of_tuples < 1) {
|
|
95
115
|
throw ruby_exception(rb_eArgError, "Array of ID/content tuples must not be empty");
|
|
96
116
|
}
|
|
97
117
|
id_content.reserve(num_of_tuples);
|
|
98
118
|
for (std::size_t i = 0; i < num_of_tuples; ++i) {
|
|
99
|
-
VALUE entry = rb_ary_entry(
|
|
119
|
+
VALUE entry = rb_ary_entry(tuples, static_cast<long>(i));
|
|
100
120
|
if (TYPE(entry) != T_ARRAY || RARRAY_LEN(entry) != 3) {
|
|
101
121
|
throw ruby_exception(rb_eArgError,
|
|
102
122
|
rb_sprintf("ID/content tuple must be represented as an Array[id, "
|
|
@@ -118,27 +138,40 @@ cb_extract_array_of_id_content(
|
|
|
118
138
|
throw ruby_exception(rb_eArgError,
|
|
119
139
|
rb_sprintf("Flags must be an Integer, but given %+" PRIsVALUE, flags));
|
|
120
140
|
}
|
|
121
|
-
id_content.emplace_back(
|
|
122
|
-
|
|
123
|
-
|
|
141
|
+
id_content.emplace_back(core::document_id{ cb_string_new(bucket_name),
|
|
142
|
+
cb_string_new(scope_name),
|
|
143
|
+
cb_string_new(collection_name),
|
|
144
|
+
cb_string_new(id) },
|
|
145
|
+
couchbase::codec::encoded_value{
|
|
146
|
+
cb_binary_new(content),
|
|
147
|
+
FIX2UINT(flags),
|
|
148
|
+
});
|
|
124
149
|
}
|
|
125
150
|
}
|
|
126
151
|
|
|
127
152
|
void
|
|
128
|
-
cb_extract_array_of_id_cas(std::vector<std::pair<
|
|
153
|
+
cb_extract_array_of_id_cas(std::vector<std::pair<core::document_id, couchbase::cas>>& id_cas,
|
|
154
|
+
VALUE bucket_name,
|
|
155
|
+
VALUE scope_name,
|
|
156
|
+
VALUE collection_name,
|
|
157
|
+
VALUE tuples)
|
|
129
158
|
{
|
|
130
|
-
|
|
159
|
+
cb_check_type(bucket_name, T_STRING);
|
|
160
|
+
cb_check_type(scope_name, T_STRING);
|
|
161
|
+
cb_check_type(collection_name, T_STRING);
|
|
162
|
+
|
|
163
|
+
if (TYPE(tuples) != T_ARRAY) {
|
|
131
164
|
throw ruby_exception(
|
|
132
165
|
rb_eArgError,
|
|
133
|
-
rb_sprintf("Type of ID/CAS tuples must be an Array, but given %+" PRIsVALUE,
|
|
166
|
+
rb_sprintf("Type of ID/CAS tuples must be an Array, but given %+" PRIsVALUE, tuples));
|
|
134
167
|
}
|
|
135
|
-
auto num_of_tuples = static_cast<std::size_t>(RARRAY_LEN(
|
|
168
|
+
auto num_of_tuples = static_cast<std::size_t>(RARRAY_LEN(tuples));
|
|
136
169
|
if (num_of_tuples < 1) {
|
|
137
170
|
rb_raise(rb_eArgError, "Array of ID/CAS tuples must not be empty");
|
|
138
171
|
}
|
|
139
172
|
id_cas.reserve(num_of_tuples);
|
|
140
173
|
for (std::size_t i = 0; i < num_of_tuples; ++i) {
|
|
141
|
-
VALUE entry = rb_ary_entry(
|
|
174
|
+
VALUE entry = rb_ary_entry(tuples, static_cast<long>(i));
|
|
142
175
|
if (TYPE(entry) != T_ARRAY || RARRAY_LEN(entry) != 2) {
|
|
143
176
|
throw ruby_exception(
|
|
144
177
|
rb_eArgError,
|
|
@@ -156,7 +189,11 @@ cb_extract_array_of_id_cas(std::vector<std::pair<std::string, couchbase::cas>>&
|
|
|
156
189
|
cb_extract_cas(cas_val, cas);
|
|
157
190
|
}
|
|
158
191
|
|
|
159
|
-
id_cas.emplace_back(cb_string_new(
|
|
192
|
+
id_cas.emplace_back(core::document_id{ cb_string_new(bucket_name),
|
|
193
|
+
cb_string_new(scope_name),
|
|
194
|
+
cb_string_new(collection_name),
|
|
195
|
+
cb_string_new(id) },
|
|
196
|
+
cas_val);
|
|
160
197
|
}
|
|
161
198
|
}
|
|
162
199
|
|
|
@@ -222,45 +259,72 @@ cb_Backend_document_upsert_multi(VALUE self,
|
|
|
222
259
|
VALUE id_content,
|
|
223
260
|
VALUE options)
|
|
224
261
|
{
|
|
225
|
-
auto cluster =
|
|
226
|
-
|
|
227
|
-
try {
|
|
228
|
-
couchbase::upsert_options opts;
|
|
229
|
-
set_timeout(opts, options);
|
|
230
|
-
set_expiry(opts, options);
|
|
231
|
-
set_durability(opts, options);
|
|
232
|
-
set_preserve_expiry(opts, options);
|
|
262
|
+
auto cluster = cb_backend_to_core_api_cluster(self);
|
|
233
263
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
264
|
+
Check_Type(bucket, T_STRING);
|
|
265
|
+
Check_Type(scope, T_STRING);
|
|
266
|
+
Check_Type(collection, T_STRING);
|
|
267
|
+
if (!NIL_P(options)) {
|
|
268
|
+
Check_Type(options, T_HASH);
|
|
269
|
+
}
|
|
237
270
|
|
|
238
|
-
|
|
239
|
-
|
|
271
|
+
try {
|
|
272
|
+
std::vector<std::pair<core::document_id, couchbase::codec::encoded_value>> tuples{};
|
|
273
|
+
cb_extract_array_of_id_content(tuples, bucket, scope, collection, id_content);
|
|
240
274
|
|
|
241
275
|
auto num_of_tuples = tuples.size();
|
|
242
|
-
std::vector<
|
|
243
|
-
std::pair<std::string, std::future<std::pair<couchbase::error, couchbase::mutation_result>>>>
|
|
244
|
-
futures;
|
|
276
|
+
std::vector<std::pair<std::string, std::future<core::operations::upsert_response>>> futures;
|
|
245
277
|
futures.reserve(num_of_tuples);
|
|
246
278
|
|
|
247
279
|
for (auto& [id, content] : tuples) {
|
|
248
|
-
|
|
280
|
+
core::operations::upsert_request req{
|
|
281
|
+
id,
|
|
282
|
+
std::move(content.data),
|
|
283
|
+
};
|
|
284
|
+
req.flags = content.flags;
|
|
285
|
+
cb_extract_timeout(req, options);
|
|
286
|
+
cb_extract_expiry(req, options);
|
|
287
|
+
cb_extract_durability_level(req, options);
|
|
288
|
+
cb_extract_preserve_expiry(req, options);
|
|
289
|
+
|
|
290
|
+
std::promise<core::operations::upsert_response> promise;
|
|
291
|
+
futures.emplace_back(id.key(), promise.get_future());
|
|
292
|
+
|
|
293
|
+
if (const auto legacy_durability = extract_legacy_durability_constraints(options);
|
|
294
|
+
legacy_durability.has_value()) {
|
|
295
|
+
cluster.execute(
|
|
296
|
+
core::operations::upsert_request_with_legacy_durability{
|
|
297
|
+
std::move(req),
|
|
298
|
+
legacy_durability.value().first,
|
|
299
|
+
legacy_durability.value().second,
|
|
300
|
+
},
|
|
301
|
+
[promise = std::move(promise)](auto&& resp) mutable {
|
|
302
|
+
promise.set_value(std::forward<decltype(resp)>(resp));
|
|
303
|
+
});
|
|
304
|
+
} else {
|
|
305
|
+
cluster.execute(std::move(req), [promise = std::move(promise)](auto&& resp) mutable {
|
|
306
|
+
promise.set_value(std::forward<decltype(resp)>(resp));
|
|
307
|
+
});
|
|
308
|
+
}
|
|
249
309
|
}
|
|
250
310
|
|
|
251
311
|
VALUE res = rb_ary_new_capa(static_cast<long>(num_of_tuples));
|
|
252
312
|
for (auto& [id, f] : futures) {
|
|
253
|
-
auto
|
|
254
|
-
VALUE entry
|
|
255
|
-
if (
|
|
313
|
+
auto resp = f.get();
|
|
314
|
+
VALUE entry;
|
|
315
|
+
if (resp.ctx.ec()) {
|
|
316
|
+
entry = rb_hash_new();
|
|
256
317
|
static const auto sym_error = rb_id2sym(rb_intern("error"));
|
|
257
|
-
rb_hash_aset(entry, sym_error, cb_map_error(
|
|
318
|
+
rb_hash_aset(entry, sym_error, cb_map_error(resp.ctx, "unable (multi)upsert"));
|
|
319
|
+
} else {
|
|
320
|
+
entry = cb_create_mutation_result(resp);
|
|
258
321
|
}
|
|
259
322
|
static const auto sym_id = rb_id2sym(rb_intern("id"));
|
|
260
323
|
rb_hash_aset(entry, sym_id, cb_str_new(id));
|
|
261
324
|
rb_ary_push(res, entry);
|
|
262
325
|
}
|
|
263
326
|
return res;
|
|
327
|
+
|
|
264
328
|
} catch (const std::system_error& se) {
|
|
265
329
|
rb_exc_raise(cb_map_error_code(
|
|
266
330
|
se.code(), fmt::format("failed to perform {}: {}", __func__, se.what()), false));
|
|
@@ -278,50 +342,69 @@ cb_Backend_document_remove_multi(VALUE self,
|
|
|
278
342
|
VALUE id_cas,
|
|
279
343
|
VALUE options)
|
|
280
344
|
{
|
|
281
|
-
auto cluster =
|
|
345
|
+
auto cluster = cb_backend_to_core_api_cluster(self);
|
|
282
346
|
|
|
347
|
+
Check_Type(bucket, T_STRING);
|
|
348
|
+
Check_Type(scope, T_STRING);
|
|
349
|
+
Check_Type(collection, T_STRING);
|
|
283
350
|
if (!NIL_P(options)) {
|
|
284
351
|
Check_Type(options, T_HASH);
|
|
285
352
|
}
|
|
286
353
|
|
|
287
354
|
try {
|
|
288
|
-
couchbase::
|
|
289
|
-
|
|
290
|
-
set_durability(opts, options);
|
|
291
|
-
|
|
292
|
-
std::vector<std::pair<std::string, couchbase::cas>> tuples{};
|
|
293
|
-
cb_extract_array_of_id_cas(tuples, id_cas);
|
|
294
|
-
|
|
295
|
-
auto c = cluster.bucket(cb_string_new(bucket))
|
|
296
|
-
.scope(cb_string_new(scope))
|
|
297
|
-
.collection(cb_string_new(collection));
|
|
355
|
+
std::vector<std::pair<core::document_id, couchbase::cas>> tuples{};
|
|
356
|
+
cb_extract_array_of_id_cas(tuples, bucket, scope, collection, id_cas);
|
|
298
357
|
|
|
299
358
|
auto num_of_tuples = tuples.size();
|
|
300
|
-
std::vector<
|
|
301
|
-
std::pair<std::string, std::future<std::pair<couchbase::error, couchbase::mutation_result>>>>
|
|
302
|
-
futures;
|
|
359
|
+
std::vector<std::pair<std::string, std::future<core::operations::remove_response>>> futures;
|
|
303
360
|
futures.reserve(num_of_tuples);
|
|
304
361
|
|
|
305
362
|
for (const auto& [id, cas] : tuples) {
|
|
306
|
-
|
|
307
|
-
|
|
363
|
+
core::operations::remove_request req{
|
|
364
|
+
id,
|
|
365
|
+
};
|
|
366
|
+
cb_extract_timeout(req, options);
|
|
367
|
+
cb_extract_durability_level(req, options);
|
|
368
|
+
req.cas = cas;
|
|
369
|
+
|
|
370
|
+
std::promise<core::operations::remove_response> promise;
|
|
371
|
+
futures.emplace_back(id.key(), promise.get_future());
|
|
372
|
+
|
|
373
|
+
if (const auto legacy_durability = extract_legacy_durability_constraints(options);
|
|
374
|
+
legacy_durability.has_value()) {
|
|
375
|
+
cluster.execute(
|
|
376
|
+
core::operations::remove_request_with_legacy_durability{
|
|
377
|
+
std::move(req),
|
|
378
|
+
legacy_durability.value().first,
|
|
379
|
+
legacy_durability.value().second,
|
|
380
|
+
},
|
|
381
|
+
[promise = std::move(promise)](auto&& resp) mutable {
|
|
382
|
+
promise.set_value(std::forward<decltype(resp)>(resp));
|
|
383
|
+
});
|
|
384
|
+
} else {
|
|
385
|
+
cluster.execute(std::move(req), [promise = std::move(promise)](auto&& resp) mutable {
|
|
386
|
+
promise.set_value(std::forward<decltype(resp)>(resp));
|
|
387
|
+
});
|
|
388
|
+
}
|
|
308
389
|
}
|
|
309
390
|
|
|
310
391
|
VALUE res = rb_ary_new_capa(static_cast<long>(num_of_tuples));
|
|
311
392
|
for (auto& [id, f] : futures) {
|
|
312
|
-
auto
|
|
313
|
-
VALUE entry
|
|
314
|
-
if (ctx.ec()) {
|
|
393
|
+
auto resp = f.get();
|
|
394
|
+
VALUE entry;
|
|
395
|
+
if (resp.ctx.ec()) {
|
|
396
|
+
entry = rb_hash_new();
|
|
315
397
|
static const auto sym_error = rb_id2sym(rb_intern("error"));
|
|
316
|
-
rb_hash_aset(entry, sym_error, cb_map_error(ctx, "unable (multi)remove"));
|
|
398
|
+
rb_hash_aset(entry, sym_error, cb_map_error(resp.ctx, "unable (multi)remove"));
|
|
399
|
+
} else {
|
|
400
|
+
entry = cb_create_mutation_result(resp);
|
|
317
401
|
}
|
|
318
402
|
static const auto sym_id = rb_id2sym(rb_intern("id"));
|
|
319
403
|
rb_hash_aset(entry, sym_id, cb_str_new(id));
|
|
320
|
-
|
|
321
404
|
rb_ary_push(res, entry);
|
|
322
405
|
}
|
|
323
|
-
|
|
324
406
|
return res;
|
|
407
|
+
|
|
325
408
|
} catch (const std::system_error& se) {
|
|
326
409
|
rb_exc_raise(cb_map_error_code(
|
|
327
410
|
se.code(), fmt::format("failed to perform {}: {}", __func__, se.what()), false));
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2025-Present Couchbase, Inc.
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include "rcb_observability.hxx"
|
|
19
|
+
|
|
20
|
+
#include "rcb_backend.hxx"
|
|
21
|
+
#include "rcb_utils.hxx"
|
|
22
|
+
|
|
23
|
+
#include <core/cluster.hxx>
|
|
24
|
+
#include <core/cluster_label_listener.hxx>
|
|
25
|
+
#include <core/tracing/wrapper_sdk_tracer.hxx>
|
|
26
|
+
|
|
27
|
+
#include <ruby.h>
|
|
28
|
+
|
|
29
|
+
#include <chrono>
|
|
30
|
+
#include <memory>
|
|
31
|
+
|
|
32
|
+
namespace couchbase::ruby
|
|
33
|
+
{
|
|
34
|
+
namespace
|
|
35
|
+
{
|
|
36
|
+
VALUE
|
|
37
|
+
core_span_to_rb_hash(std::shared_ptr<couchbase::core::tracing::wrapper_sdk_span> core_span)
|
|
38
|
+
{
|
|
39
|
+
VALUE res = rb_hash_new();
|
|
40
|
+
|
|
41
|
+
static VALUE sym_name = rb_id2sym(rb_intern("name"));
|
|
42
|
+
static VALUE sym_attributes = rb_id2sym(rb_intern("attributes"));
|
|
43
|
+
static VALUE sym_start_timestamp = rb_id2sym(rb_intern("start_timestamp"));
|
|
44
|
+
static VALUE sym_end_timestamp = rb_id2sym(rb_intern("end_timestamp"));
|
|
45
|
+
static VALUE sym_children = rb_id2sym(rb_intern("children"));
|
|
46
|
+
|
|
47
|
+
VALUE attributes = rb_hash_new();
|
|
48
|
+
|
|
49
|
+
for (const auto& [key, value] : core_span->uint_tags()) {
|
|
50
|
+
rb_hash_aset(attributes, cb_str_new(key), ULL2NUM(value));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
for (const auto& [key, value] : core_span->string_tags()) {
|
|
54
|
+
rb_hash_aset(attributes, cb_str_new(key), cb_str_new(value));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
rb_hash_aset(res, sym_name, cb_str_new(core_span->name()));
|
|
58
|
+
rb_hash_aset(res, sym_attributes, attributes);
|
|
59
|
+
rb_hash_aset(res,
|
|
60
|
+
sym_start_timestamp,
|
|
61
|
+
LL2NUM(std::chrono::duration_cast<std::chrono::microseconds>(
|
|
62
|
+
core_span->start_time().time_since_epoch())
|
|
63
|
+
.count()));
|
|
64
|
+
rb_hash_aset(res,
|
|
65
|
+
sym_end_timestamp,
|
|
66
|
+
LL2NUM(std::chrono::duration_cast<std::chrono::microseconds>(
|
|
67
|
+
core_span->end_time().time_since_epoch())
|
|
68
|
+
.count()));
|
|
69
|
+
|
|
70
|
+
VALUE children = rb_ary_new_capa(static_cast<long>(core_span->children().size()));
|
|
71
|
+
for (const auto& child : core_span->children()) {
|
|
72
|
+
rb_ary_push(children, core_span_to_rb_hash(child));
|
|
73
|
+
}
|
|
74
|
+
rb_hash_aset(res, sym_children, children);
|
|
75
|
+
|
|
76
|
+
return res;
|
|
77
|
+
}
|
|
78
|
+
} // namespace
|
|
79
|
+
|
|
80
|
+
void
|
|
81
|
+
cb_add_core_spans(VALUE observability_handler,
|
|
82
|
+
std::shared_ptr<couchbase::core::tracing::wrapper_sdk_span> parent_span,
|
|
83
|
+
std::size_t retry_attempts)
|
|
84
|
+
{
|
|
85
|
+
const auto children = parent_span->children();
|
|
86
|
+
VALUE spans = rb_ary_new_capa(static_cast<long>(children.size()));
|
|
87
|
+
|
|
88
|
+
for (const auto& child : parent_span->children()) {
|
|
89
|
+
rb_ary_push(spans, core_span_to_rb_hash(child));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
static ID add_backend_spans_func = rb_intern("add_spans_from_backend");
|
|
93
|
+
rb_funcall(observability_handler, add_backend_spans_func, 1, spans);
|
|
94
|
+
|
|
95
|
+
static ID add_retries_func = rb_intern("add_retries");
|
|
96
|
+
rb_funcall(observability_handler, add_retries_func, 1, ULONG2NUM(retry_attempts));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
namespace
|
|
100
|
+
{
|
|
101
|
+
VALUE
|
|
102
|
+
cb_Backend_cluster_labels(VALUE self)
|
|
103
|
+
{
|
|
104
|
+
VALUE res = rb_hash_new();
|
|
105
|
+
{
|
|
106
|
+
auto cluster = cb_backend_to_core_api_cluster(self);
|
|
107
|
+
auto labels = cluster.cluster_label_listener()->cluster_labels();
|
|
108
|
+
|
|
109
|
+
static const auto sym_cluster_name = rb_id2sym(rb_intern("cluster_name"));
|
|
110
|
+
static const auto sym_cluster_uuid = rb_id2sym(rb_intern("cluster_uuid"));
|
|
111
|
+
|
|
112
|
+
if (labels.cluster_name.has_value()) {
|
|
113
|
+
rb_hash_aset(res, sym_cluster_name, cb_str_new(labels.cluster_name.value()));
|
|
114
|
+
} else {
|
|
115
|
+
rb_hash_aset(res, sym_cluster_name, Qnil);
|
|
116
|
+
}
|
|
117
|
+
if (labels.cluster_uuid.has_value()) {
|
|
118
|
+
rb_hash_aset(res, sym_cluster_uuid, cb_str_new(labels.cluster_uuid.value()));
|
|
119
|
+
} else {
|
|
120
|
+
rb_hash_aset(res, sym_cluster_uuid, Qnil);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return res;
|
|
124
|
+
}
|
|
125
|
+
} // namespace
|
|
126
|
+
|
|
127
|
+
void
|
|
128
|
+
init_observability(VALUE cBackend)
|
|
129
|
+
{
|
|
130
|
+
rb_define_method(cBackend, "cluster_labels", cb_Backend_cluster_labels, 0);
|
|
131
|
+
}
|
|
132
|
+
} // namespace couchbase::ruby
|