couchbase 4.2.11-rc.1 → 4.2.11
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.
- package/deps/couchbase-cxx-client/CMakeLists.txt +1 -0
- package/deps/couchbase-cxx-client/cmake/ThirdPartyDependencies.cmake +2 -0
- package/deps/couchbase-cxx-client/core/bucket.cxx +2 -2
- package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +11 -0
- package/deps/couchbase-cxx-client/core/io/mcbp_session.hxx +1 -0
- package/deps/couchbase-cxx-client/core/range_scan_load_balancer.cxx +141 -0
- package/deps/couchbase-cxx-client/core/range_scan_load_balancer.hxx +64 -0
- package/deps/couchbase-cxx-client/core/range_scan_orchestrator.cxx +224 -336
- package/deps/couchbase-cxx-client/core/range_scan_orchestrator.hxx +5 -6
- package/deps/couchbase-cxx-client/core/range_scan_orchestrator_options.hxx +6 -4
- package/deps/couchbase-cxx-client/core/scan_result.hxx +1 -11
- package/deps/couchbase-cxx-client/couchbase/bucket.hxx +2 -2
- package/deps/couchbase-cxx-client/couchbase/cluster.hxx +1 -1
- package/deps/couchbase-cxx-client/couchbase/collection.hxx +1 -0
- package/deps/couchbase-cxx-client/couchbase/collection_query_index_manager.hxx +1 -1
- package/deps/couchbase-cxx-client/couchbase/error_context.hxx +1 -0
- package/deps/couchbase-cxx-client/couchbase/get_links_analytics_options.hxx +2 -2
- package/deps/couchbase-cxx-client/couchbase/scope.hxx +1 -1
- package/deps/couchbase-cxx-client/couchbase/search_options.hxx +2 -2
- package/deps/couchbase-cxx-client/couchbase/search_result.hxx +1 -1
- package/deps/couchbase-cxx-client/couchbase/subdocument_error_context.hxx +1 -0
- package/deps/couchbase-cxx-client/couchbase/transactions/transaction_options.hxx +1 -1
- package/deps/couchbase-cxx-client/couchbase-sdk-cxx-black-duck-manifest.yaml +1 -0
- package/package.json +7 -7
- package/src/jstocbpp_autogen.hpp +0 -1
- package/deps/couchbase-cxx-client/core/scan_options.hxx +0 -44
@@ -360,6 +360,7 @@ set(couchbase_cxx_client_FILES
|
|
360
360
|
core/protocol/cmd_upsert.cxx
|
361
361
|
core/protocol/frame_info_utils.cxx
|
362
362
|
core/protocol/status.cxx
|
363
|
+
core/range_scan_load_balancer.cxx
|
363
364
|
core/range_scan_options.cxx
|
364
365
|
core/range_scan_orchestrator.cxx
|
365
366
|
core/retry_orchestrator.cxx
|
@@ -495,7 +495,7 @@ class bucket_impl
|
|
495
495
|
std::size_t i = start;
|
496
496
|
do {
|
497
497
|
auto ptr = sessions_.find(i % sessions_.size());
|
498
|
-
if (ptr != sessions_.end() && ptr->second.supports_gcccp()) {
|
498
|
+
if (ptr != sessions_.end() && ptr->second.is_bootstrapped() && ptr->second.supports_gcccp()) {
|
499
499
|
session = ptr->second;
|
500
500
|
}
|
501
501
|
i = heartbeat_next_index_.fetch_add(1);
|
@@ -506,7 +506,7 @@ class bucket_impl
|
|
506
506
|
req.opaque(session->next_opaque());
|
507
507
|
session->write_and_flush(req.data());
|
508
508
|
} else {
|
509
|
-
CB_LOG_WARNING(R"({} unable to find session with GCCCP support, retry in {})", log_prefix_, heartbeat_interval_);
|
509
|
+
CB_LOG_WARNING(R"({} unable to find connected session with GCCCP support, retry in {})", log_prefix_, heartbeat_interval_);
|
510
510
|
}
|
511
511
|
}
|
512
512
|
|
@@ -920,6 +920,11 @@ class mcbp_session_impl
|
|
920
920
|
return stopped_;
|
921
921
|
}
|
922
922
|
|
923
|
+
[[nodiscard]] bool is_bootstrapped() const
|
924
|
+
{
|
925
|
+
return bootstrapped_;
|
926
|
+
}
|
927
|
+
|
923
928
|
void on_stop(utils::movable_function<void()> handler)
|
924
929
|
{
|
925
930
|
on_stop_handler_ = std::move(handler);
|
@@ -1739,6 +1744,12 @@ mcbp_session::is_stopped() const
|
|
1739
1744
|
return impl_->is_stopped();
|
1740
1745
|
}
|
1741
1746
|
|
1747
|
+
bool
|
1748
|
+
mcbp_session::is_bootstrapped() const
|
1749
|
+
{
|
1750
|
+
return impl_->is_bootstrapped();
|
1751
|
+
}
|
1752
|
+
|
1742
1753
|
std::uint32_t
|
1743
1754
|
mcbp_session::next_opaque()
|
1744
1755
|
{
|
@@ -97,6 +97,7 @@ class mcbp_session
|
|
97
97
|
[[nodiscard]] const std::string& log_prefix() const;
|
98
98
|
[[nodiscard]] bool cancel(std::uint32_t opaque, std::error_code ec, retry_reason reason);
|
99
99
|
[[nodiscard]] bool is_stopped() const;
|
100
|
+
[[nodiscard]] bool is_bootstrapped() const;
|
100
101
|
[[nodiscard]] std::uint32_t next_opaque();
|
101
102
|
[[nodiscard]] std::optional<std::uint32_t> get_collection_uid(const std::string& collection_path);
|
102
103
|
[[nodiscard]] mcbp_context context() const;
|
@@ -0,0 +1,141 @@
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
2
|
+
/*
|
3
|
+
* Copyright 2024. 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 "range_scan_load_balancer.hxx"
|
19
|
+
|
20
|
+
#include <algorithm>
|
21
|
+
#include <limits>
|
22
|
+
#include <map>
|
23
|
+
#include <numeric>
|
24
|
+
#include <queue>
|
25
|
+
#include <random>
|
26
|
+
#include <vector>
|
27
|
+
|
28
|
+
namespace couchbase::core
|
29
|
+
{
|
30
|
+
range_scan_node_state::range_scan_node_state(std::queue<std::uint16_t> vbuckets)
|
31
|
+
: pending_vbuckets_{ std::move(vbuckets) }
|
32
|
+
{
|
33
|
+
}
|
34
|
+
|
35
|
+
auto
|
36
|
+
range_scan_node_state::fetch_vbucket_id() -> std::optional<std::uint16_t>
|
37
|
+
{
|
38
|
+
std::lock_guard<std::mutex> const lock{ mutex_ };
|
39
|
+
if (pending_vbuckets_.empty()) {
|
40
|
+
return {};
|
41
|
+
}
|
42
|
+
active_stream_count_++;
|
43
|
+
auto vbucket_id = pending_vbuckets_.front();
|
44
|
+
pending_vbuckets_.pop();
|
45
|
+
return vbucket_id;
|
46
|
+
}
|
47
|
+
|
48
|
+
void
|
49
|
+
range_scan_node_state::notify_stream_ended()
|
50
|
+
{
|
51
|
+
std::lock_guard<std::mutex> const lock{ mutex_ };
|
52
|
+
active_stream_count_--;
|
53
|
+
}
|
54
|
+
|
55
|
+
void
|
56
|
+
range_scan_node_state::enqueue_vbucket(std::uint16_t vbucket_id)
|
57
|
+
{
|
58
|
+
std::lock_guard<std::mutex> const lock{ mutex_ };
|
59
|
+
pending_vbuckets_.push(vbucket_id);
|
60
|
+
}
|
61
|
+
|
62
|
+
auto
|
63
|
+
range_scan_node_state::active_stream_count() -> std::uint16_t
|
64
|
+
{
|
65
|
+
std::lock_guard<std::mutex> const lock{ mutex_ };
|
66
|
+
return active_stream_count_;
|
67
|
+
}
|
68
|
+
|
69
|
+
auto
|
70
|
+
range_scan_node_state::pending_vbucket_count() -> std::size_t
|
71
|
+
{
|
72
|
+
std::lock_guard<std::mutex> const lock{ mutex_ };
|
73
|
+
return pending_vbuckets_.size();
|
74
|
+
}
|
75
|
+
|
76
|
+
range_scan_load_balancer::range_scan_load_balancer(const topology::configuration::vbucket_map& vbucket_map,
|
77
|
+
std::optional<std::uint64_t> seed)
|
78
|
+
: seed_{ seed }
|
79
|
+
{
|
80
|
+
std::map<std::int16_t, std::queue<std::uint16_t>> node_to_vbucket_map{};
|
81
|
+
for (std::uint16_t vbucket_id = 0; vbucket_id < vbucket_map.size(); vbucket_id++) {
|
82
|
+
auto node_id = vbucket_map[vbucket_id][0];
|
83
|
+
node_to_vbucket_map[node_id].push(vbucket_id);
|
84
|
+
}
|
85
|
+
for (auto [node_id, vbucket_ids] : node_to_vbucket_map) {
|
86
|
+
nodes_.emplace(node_id, std::move(vbucket_ids));
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
void
|
91
|
+
range_scan_load_balancer::seed(std::uint64_t seed)
|
92
|
+
{
|
93
|
+
seed_ = seed;
|
94
|
+
}
|
95
|
+
|
96
|
+
auto
|
97
|
+
range_scan_load_balancer::select_vbucket() -> std::optional<std::uint16_t>
|
98
|
+
{
|
99
|
+
std::lock_guard<std::mutex> const lock{ select_vbucket_mutex_ };
|
100
|
+
|
101
|
+
auto min_stream_count = std::numeric_limits<std::uint16_t>::max();
|
102
|
+
std::optional<std::int16_t> selected_node_id{};
|
103
|
+
|
104
|
+
std::vector<std::map<int16_t, range_scan_node_state>::iterator> iterators{ nodes_.size() };
|
105
|
+
|
106
|
+
std::iota(iterators.begin(), iterators.end(), nodes_.begin());
|
107
|
+
std::mt19937_64 gen{ std::random_device{}() };
|
108
|
+
if (seed_.has_value()) {
|
109
|
+
gen.seed(seed_.value());
|
110
|
+
}
|
111
|
+
std::shuffle(iterators.begin(), iterators.end(), gen);
|
112
|
+
|
113
|
+
for (auto it : iterators) {
|
114
|
+
auto& [node_id, node_status] = *it;
|
115
|
+
auto stream_count = node_status.active_stream_count();
|
116
|
+
|
117
|
+
if (stream_count < min_stream_count && node_status.pending_vbucket_count() > 0) {
|
118
|
+
min_stream_count = stream_count;
|
119
|
+
selected_node_id = node_id;
|
120
|
+
}
|
121
|
+
}
|
122
|
+
|
123
|
+
if (!selected_node_id) {
|
124
|
+
return {};
|
125
|
+
}
|
126
|
+
|
127
|
+
return nodes_.at(selected_node_id.value()).fetch_vbucket_id();
|
128
|
+
}
|
129
|
+
|
130
|
+
void
|
131
|
+
range_scan_load_balancer::notify_stream_ended(std::int16_t node_id)
|
132
|
+
{
|
133
|
+
nodes_.at(node_id).notify_stream_ended();
|
134
|
+
}
|
135
|
+
|
136
|
+
void
|
137
|
+
range_scan_load_balancer::enqueue_vbucket(std::int16_t node_id, std::uint16_t vbucket_id)
|
138
|
+
{
|
139
|
+
nodes_.at(node_id).enqueue_vbucket(vbucket_id);
|
140
|
+
}
|
141
|
+
} // namespace couchbase::core
|
@@ -0,0 +1,64 @@
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
2
|
+
/*
|
3
|
+
* Copyright 2024. 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 "core/logger/logger.hxx"
|
19
|
+
#include "core/topology/configuration.hxx"
|
20
|
+
|
21
|
+
#include <mutex>
|
22
|
+
#include <queue>
|
23
|
+
|
24
|
+
namespace couchbase::core
|
25
|
+
{
|
26
|
+
class range_scan_node_state
|
27
|
+
{
|
28
|
+
public:
|
29
|
+
range_scan_node_state(std::queue<std::uint16_t> vbuckets);
|
30
|
+
|
31
|
+
auto fetch_vbucket_id() -> std::optional<std::uint16_t>;
|
32
|
+
void notify_stream_ended();
|
33
|
+
void enqueue_vbucket(std::uint16_t vbucket_id);
|
34
|
+
auto active_stream_count() -> std::uint16_t;
|
35
|
+
auto pending_vbucket_count() -> std::size_t;
|
36
|
+
|
37
|
+
private:
|
38
|
+
std::uint16_t active_stream_count_{ 0 };
|
39
|
+
std::queue<std::uint16_t> pending_vbuckets_{};
|
40
|
+
std::mutex mutex_{};
|
41
|
+
};
|
42
|
+
|
43
|
+
class range_scan_load_balancer
|
44
|
+
{
|
45
|
+
public:
|
46
|
+
range_scan_load_balancer(const topology::configuration::vbucket_map& vbucket_map, std::optional<std::uint64_t> seed = {});
|
47
|
+
|
48
|
+
void seed(std::uint64_t seed);
|
49
|
+
|
50
|
+
/**
|
51
|
+
* Returns the ID of a vbucket that corresponds to the node with the lowest number of active streams.
|
52
|
+
* Returns "std::nullopt" if there are no pending vbuckets
|
53
|
+
*/
|
54
|
+
auto select_vbucket() -> std::optional<std::uint16_t>;
|
55
|
+
|
56
|
+
void notify_stream_ended(std::int16_t node_id);
|
57
|
+
void enqueue_vbucket(std::int16_t node_id, std::uint16_t vbucket_id);
|
58
|
+
|
59
|
+
private:
|
60
|
+
std::map<std::int16_t, range_scan_node_state> nodes_{};
|
61
|
+
std::mutex select_vbucket_mutex_{};
|
62
|
+
std::optional<std::uint64_t> seed_{};
|
63
|
+
};
|
64
|
+
} // namespace couchbase::core
|