couchbase 4.2.5-dev.3 → 4.2.6-dev
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/README.md +81 -9
- package/deps/couchbase-cxx-client/CMakeLists.txt +9 -1
- package/deps/couchbase-cxx-client/bin/api.rb +234 -0
- package/deps/couchbase-cxx-client/bin/create-search-index +18 -135
- package/deps/couchbase-cxx-client/bin/init-cluster +17 -139
- package/deps/couchbase-cxx-client/bin/load-sample-buckets +54 -0
- package/deps/couchbase-cxx-client/core/cluster.hxx +33 -12
- package/deps/couchbase-cxx-client/core/cluster_options.hxx +3 -0
- package/deps/couchbase-cxx-client/core/crud_component.cxx +51 -22
- package/deps/couchbase-cxx-client/core/impl/build_deferred_query_indexes.cxx +115 -50
- package/deps/couchbase-cxx-client/core/impl/cluster.cxx +6 -0
- package/deps/couchbase-cxx-client/core/impl/create_bucket.cxx +155 -0
- package/deps/couchbase-cxx-client/core/impl/create_query_index.cxx +172 -59
- package/deps/couchbase-cxx-client/core/impl/dns_srv_tracker.cxx +2 -1
- package/deps/couchbase-cxx-client/core/impl/drop_bucket.cxx +66 -0
- package/deps/couchbase-cxx-client/core/impl/drop_query_index.cxx +138 -59
- package/deps/couchbase-cxx-client/core/impl/flush_bucket.cxx +66 -0
- package/deps/couchbase-cxx-client/core/impl/get_all_buckets.cxx +163 -0
- package/deps/couchbase-cxx-client/core/impl/get_all_query_indexes.cxx +67 -37
- package/deps/couchbase-cxx-client/core/impl/get_bucket.cxx +153 -0
- package/deps/couchbase-cxx-client/core/impl/internal_manager_error_context.cxx +113 -0
- package/deps/couchbase-cxx-client/core/impl/internal_manager_error_context.hxx +60 -0
- package/deps/couchbase-cxx-client/core/impl/key_value_error_category.cxx +2 -4
- package/deps/couchbase-cxx-client/core/impl/manager_error_context.cxx +100 -0
- package/deps/couchbase-cxx-client/core/impl/query.cxx +1 -0
- package/deps/couchbase-cxx-client/core/impl/update_bucket.cxx +130 -0
- package/deps/couchbase-cxx-client/core/impl/watch_query_indexes.cxx +53 -29
- package/deps/couchbase-cxx-client/core/io/dns_client.cxx +71 -38
- package/deps/couchbase-cxx-client/core/io/dns_config.cxx +5 -4
- package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +5 -6
- package/deps/couchbase-cxx-client/core/meta/features.hxx +6 -0
- package/deps/couchbase-cxx-client/core/operations/document_query.cxx +11 -0
- package/deps/couchbase-cxx-client/core/operations/document_query.hxx +1 -0
- package/deps/couchbase-cxx-client/core/origin.cxx +270 -0
- package/deps/couchbase-cxx-client/core/origin.hxx +2 -0
- package/deps/couchbase-cxx-client/core/protocol/status.cxx +2 -2
- package/deps/couchbase-cxx-client/core/range_scan_options.cxx +3 -27
- package/deps/couchbase-cxx-client/core/range_scan_options.hxx +13 -17
- package/deps/couchbase-cxx-client/core/range_scan_orchestrator.cxx +367 -170
- package/deps/couchbase-cxx-client/core/range_scan_orchestrator.hxx +13 -2
- package/deps/couchbase-cxx-client/core/range_scan_orchestrator_options.hxx +5 -3
- package/deps/couchbase-cxx-client/core/scan_options.hxx +0 -19
- package/deps/couchbase-cxx-client/core/scan_result.cxx +19 -5
- package/deps/couchbase-cxx-client/core/scan_result.hxx +5 -2
- package/deps/couchbase-cxx-client/core/timeout_defaults.hxx +2 -3
- package/deps/couchbase-cxx-client/core/topology/capabilities.hxx +1 -0
- package/deps/couchbase-cxx-client/core/topology/capabilities_fmt.hxx +2 -0
- package/deps/couchbase-cxx-client/core/topology/collections_manifest_fmt.hxx +1 -1
- package/deps/couchbase-cxx-client/core/topology/configuration.hxx +5 -0
- package/deps/couchbase-cxx-client/core/topology/configuration_json.hxx +2 -0
- package/deps/couchbase-cxx-client/core/utils/connection_string.cxx +4 -0
- package/deps/couchbase-cxx-client/couchbase/behavior_options.hxx +19 -2
- package/deps/couchbase-cxx-client/couchbase/bucket_manager.hxx +135 -0
- package/deps/couchbase-cxx-client/couchbase/build_query_index_options.hxx +0 -30
- package/deps/couchbase-cxx-client/couchbase/cluster.hxx +14 -0
- package/deps/couchbase-cxx-client/couchbase/collection_query_index_manager.hxx +7 -48
- package/deps/couchbase-cxx-client/couchbase/create_bucket_options.hxx +41 -0
- package/deps/couchbase-cxx-client/couchbase/create_primary_query_index_options.hxx +0 -29
- package/deps/couchbase-cxx-client/couchbase/create_query_index_options.hxx +0 -33
- package/deps/couchbase-cxx-client/couchbase/drop_bucket_options.hxx +41 -0
- package/deps/couchbase-cxx-client/couchbase/drop_primary_query_index_options.hxx +0 -30
- package/deps/couchbase-cxx-client/couchbase/drop_query_index_options.hxx +0 -31
- package/deps/couchbase-cxx-client/couchbase/error_codes.hxx +1 -2
- package/deps/couchbase-cxx-client/couchbase/flush_bucket_options.hxx +41 -0
- package/deps/couchbase-cxx-client/couchbase/get_all_buckets_options.hxx +44 -0
- package/deps/couchbase-cxx-client/couchbase/get_all_query_indexes_options.hxx +0 -30
- package/deps/couchbase-cxx-client/couchbase/get_bucket_options.hxx +43 -0
- package/deps/couchbase-cxx-client/couchbase/management/bucket_settings.hxx +116 -0
- package/deps/couchbase-cxx-client/couchbase/manager_error_context.hxx +29 -53
- package/deps/couchbase-cxx-client/couchbase/query_index_manager.hxx +16 -83
- package/deps/couchbase-cxx-client/couchbase/query_options.hxx +18 -0
- package/deps/couchbase-cxx-client/couchbase/security_options.hxx +15 -0
- package/deps/couchbase-cxx-client/couchbase/update_bucket_options.hxx +41 -0
- package/deps/couchbase-cxx-client/couchbase/watch_query_indexes_options.hxx +0 -31
- package/deps/couchbase-cxx-client/docs/cbc-analytics.md +1 -0
- package/deps/couchbase-cxx-client/docs/cbc-get.md +1 -0
- package/deps/couchbase-cxx-client/docs/cbc-pillowfight.md +1 -0
- package/deps/couchbase-cxx-client/docs/cbc-query.md +1 -0
- package/deps/couchbase-cxx-client/docs/cbc.md +10 -0
- package/deps/couchbase-cxx-client/test/CMakeLists.txt +1 -0
- package/deps/couchbase-cxx-client/test/test_integration_collections.cxx +6 -0
- package/deps/couchbase-cxx-client/test/test_integration_crud.cxx +5 -0
- package/deps/couchbase-cxx-client/test/test_integration_examples.cxx +137 -1
- package/deps/couchbase-cxx-client/test/test_integration_management.cxx +709 -266
- package/deps/couchbase-cxx-client/test/test_integration_query.cxx +19 -7
- package/deps/couchbase-cxx-client/test/test_integration_range_scan.cxx +351 -112
- package/deps/couchbase-cxx-client/test/test_integration_search.cxx +10 -1
- package/deps/couchbase-cxx-client/test/test_transaction_public_async_api.cxx +13 -12
- package/deps/couchbase-cxx-client/test/test_transaction_public_blocking_api.cxx +27 -21
- package/deps/couchbase-cxx-client/test/test_unit_query.cxx +75 -0
- package/deps/couchbase-cxx-client/test/utils/server_version.hxx +5 -0
- package/deps/couchbase-cxx-client/test/utils/wait_until.cxx +29 -10
- package/deps/couchbase-cxx-client/test/utils/wait_until.hxx +3 -1
- package/deps/couchbase-cxx-client/tools/utils.cxx +4 -1
- package/dist/binding.d.ts +21 -16
- package/dist/binding.js +1 -4
- package/dist/bindingutilities.d.ts +6 -1
- package/dist/bindingutilities.js +36 -1
- package/dist/collection.d.ts +65 -3
- package/dist/collection.js +107 -0
- package/dist/crudoptypes.d.ts +34 -0
- package/dist/crudoptypes.js +18 -1
- package/dist/queryexecutor.js +1 -0
- package/dist/querytypes.d.ts +7 -0
- package/dist/rangeScan.d.ts +107 -0
- package/dist/rangeScan.js +91 -0
- package/dist/streamablepromises.d.ts +6 -0
- package/dist/streamablepromises.js +25 -1
- package/package.json +13 -14
- package/scripts/createPlatformPackages.js +1 -4
- package/src/addondata.hpp +1 -0
- package/src/binding.cpp +5 -2
- package/src/connection.cpp +108 -2
- package/src/connection.hpp +1 -0
- package/src/constants.cpp +2 -12
- package/src/jstocbpp_autogen.hpp +49 -22
- package/src/jstocbpp_basic.hpp +2 -8
- package/src/mutationtoken.cpp +13 -0
- package/src/scan_iterator.cpp +90 -0
- package/src/scan_iterator.hpp +30 -0
- package/tools/gen-bindings-json.py +9 -8
- package/deps/couchbase-cxx-client/core/impl/collection_query_index_manager.cxx +0 -93
|
@@ -24,16 +24,6 @@
|
|
|
24
24
|
|
|
25
25
|
namespace couchbase::core::impl
|
|
26
26
|
{
|
|
27
|
-
|
|
28
|
-
template<typename Response>
|
|
29
|
-
static manager_error_context
|
|
30
|
-
build_context(Response& resp, std::optional<std::error_code> ec = {})
|
|
31
|
-
{
|
|
32
|
-
return { ec ? ec.value() : resp.ctx.ec, resp.ctx.last_dispatched_to, resp.ctx.last_dispatched_from,
|
|
33
|
-
resp.ctx.retry_attempts, std::move(resp.ctx.retry_reasons), std::move(resp.ctx.client_context_id),
|
|
34
|
-
resp.ctx.http_status, std::move(resp.ctx.http_body), std::move(resp.ctx.path) };
|
|
35
|
-
}
|
|
36
|
-
|
|
37
27
|
class watch_context : public std::enable_shared_from_this<watch_context>
|
|
38
28
|
{
|
|
39
29
|
|
|
@@ -50,9 +40,18 @@ class watch_context : public std::enable_shared_from_this<watch_context>
|
|
|
50
40
|
std::chrono::milliseconds timeout_{ options_.timeout.value_or(core_->origin().second.options().query_timeout) };
|
|
51
41
|
std::atomic<size_t> attempts_{ 0 };
|
|
52
42
|
|
|
53
|
-
|
|
43
|
+
template<typename Response>
|
|
44
|
+
void finish(Response& resp, std::optional<std::error_code> ec = {})
|
|
54
45
|
{
|
|
55
|
-
handler_(
|
|
46
|
+
handler_({ manager_error_context(internal_manager_error_context{ ec ? ec.value() : resp.ctx.ec,
|
|
47
|
+
resp.ctx.last_dispatched_to,
|
|
48
|
+
resp.ctx.last_dispatched_from,
|
|
49
|
+
resp.ctx.retry_attempts,
|
|
50
|
+
std::move(resp.ctx.retry_reasons),
|
|
51
|
+
std::move(resp.ctx.client_context_id),
|
|
52
|
+
resp.ctx.http_status,
|
|
53
|
+
std::move(resp.ctx.http_body),
|
|
54
|
+
std::move(resp.ctx.path) }) });
|
|
56
55
|
timer_.cancel();
|
|
57
56
|
}
|
|
58
57
|
std::chrono::milliseconds remaining()
|
|
@@ -79,9 +78,9 @@ class watch_context : public std::enable_shared_from_this<watch_context>
|
|
|
79
78
|
complete &= it != resp.indexes.end() && it->state == "online";
|
|
80
79
|
}
|
|
81
80
|
if (complete || resp.ctx.ec == couchbase::errc::common::ambiguous_timeout) {
|
|
82
|
-
finish(
|
|
81
|
+
finish(resp);
|
|
83
82
|
} else if (remaining().count() <= 0) {
|
|
84
|
-
finish(
|
|
83
|
+
finish(resp, couchbase::errc::common::ambiguous_timeout);
|
|
85
84
|
complete = true;
|
|
86
85
|
}
|
|
87
86
|
return complete;
|
|
@@ -141,28 +140,53 @@ class watch_context : public std::enable_shared_from_this<watch_context>
|
|
|
141
140
|
core_->execute(req, resp_fn);
|
|
142
141
|
}
|
|
143
142
|
};
|
|
143
|
+
} // namespace couchbase::core::impl
|
|
144
144
|
|
|
145
|
+
namespace couchbase
|
|
146
|
+
{
|
|
145
147
|
void
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
query_context query_ctx,
|
|
151
|
-
std::string collection_name,
|
|
152
|
-
watch_query_indexes_handler&& handler)
|
|
148
|
+
query_index_manager::watch_indexes(std::string bucket_name,
|
|
149
|
+
std::vector<std::string> index_names,
|
|
150
|
+
const couchbase::watch_query_indexes_options& options,
|
|
151
|
+
couchbase::watch_query_indexes_handler&& handler)
|
|
153
152
|
{
|
|
154
|
-
auto ctx = std::make_shared<watch_context>(
|
|
153
|
+
auto ctx = std::make_shared<couchbase::core::impl::watch_context>(
|
|
154
|
+
core_, std::move(bucket_name), std::move(index_names), options.build(), core::query_context{}, "", std::move(handler));
|
|
155
155
|
ctx->execute();
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
+
auto
|
|
159
|
+
query_index_manager::watch_indexes(std::string bucket_name,
|
|
160
|
+
std::vector<std::string> index_names,
|
|
161
|
+
const couchbase::watch_query_indexes_options& options) -> std::future<manager_error_context>
|
|
162
|
+
{
|
|
163
|
+
auto barrier = std::make_shared<std::promise<manager_error_context>>();
|
|
164
|
+
watch_indexes(
|
|
165
|
+
std::move(bucket_name), std::move(index_names), options, [barrier](auto ctx) mutable { barrier->set_value(std::move(ctx)); });
|
|
166
|
+
return barrier->get_future();
|
|
167
|
+
}
|
|
168
|
+
|
|
158
169
|
void
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
couchbase::watch_query_indexes_options::built options,
|
|
163
|
-
watch_query_indexes_handler&& handler)
|
|
170
|
+
collection_query_index_manager::watch_indexes(std::vector<std::string> index_names,
|
|
171
|
+
const watch_query_indexes_options& options,
|
|
172
|
+
watch_query_indexes_handler&& handler) const
|
|
164
173
|
{
|
|
165
|
-
|
|
174
|
+
auto ctx = std::make_shared<couchbase::core::impl::watch_context>(core_,
|
|
175
|
+
bucket_name_,
|
|
176
|
+
std::move(index_names),
|
|
177
|
+
options.build(),
|
|
178
|
+
core::query_context(bucket_name_, scope_name_),
|
|
179
|
+
collection_name_,
|
|
180
|
+
std::move(handler));
|
|
181
|
+
ctx->execute();
|
|
166
182
|
}
|
|
167
183
|
|
|
168
|
-
|
|
184
|
+
auto
|
|
185
|
+
collection_query_index_manager::watch_indexes(std::vector<std::string> index_names, const couchbase::watch_query_indexes_options& options)
|
|
186
|
+
-> std::future<manager_error_context>
|
|
187
|
+
{
|
|
188
|
+
auto barrier = std::make_shared<std::promise<manager_error_context>>();
|
|
189
|
+
watch_indexes(std::move(index_names), options, [barrier](auto ctx) mutable { barrier->set_value(std::move(ctx)); });
|
|
190
|
+
return barrier->get_future();
|
|
191
|
+
}
|
|
192
|
+
} // namespace couchbase
|
|
@@ -28,6 +28,10 @@
|
|
|
28
28
|
#include <asio/read.hpp>
|
|
29
29
|
#include <asio/write.hpp>
|
|
30
30
|
|
|
31
|
+
#include <fmt/chrono.h>
|
|
32
|
+
|
|
33
|
+
#include <spdlog/fmt/bin_to_hex.h>
|
|
34
|
+
|
|
31
35
|
#include <memory>
|
|
32
36
|
#include <sstream>
|
|
33
37
|
|
|
@@ -68,13 +72,22 @@ class dns_srv_command : public std::enable_shared_from_this<dns_srv_command>
|
|
|
68
72
|
|
|
69
73
|
void execute(std::chrono::milliseconds total_timeout, std::chrono::milliseconds udp_timeout)
|
|
70
74
|
{
|
|
75
|
+
CB_LOG_TRACE("Query DNS-SRV (UDP) address=\"{}:{}\", udp_timeout={}, total_timeout={}{:a}",
|
|
76
|
+
address_.to_string(),
|
|
77
|
+
port_,
|
|
78
|
+
udp_timeout,
|
|
79
|
+
total_timeout,
|
|
80
|
+
spdlog::to_hex(send_buf_));
|
|
71
81
|
asio::ip::udp::endpoint endpoint(address_, port_);
|
|
72
82
|
udp_.open(endpoint.protocol());
|
|
73
83
|
udp_.async_send_to(
|
|
74
84
|
asio::buffer(send_buf_), endpoint, [self = shared_from_this()](std::error_code ec1, std::size_t /* bytes_transferred */) mutable {
|
|
75
85
|
if (ec1) {
|
|
76
86
|
self->udp_deadline_.cancel();
|
|
77
|
-
CB_LOG_DEBUG("DNS UDP write operation has got error
|
|
87
|
+
CB_LOG_DEBUG("DNS UDP write operation has got error, retrying with TCP, address=\"{}:{}\", ec={}",
|
|
88
|
+
self->address_.to_string(),
|
|
89
|
+
self->port_,
|
|
90
|
+
ec1.message());
|
|
78
91
|
return self->retry_with_tcp();
|
|
79
92
|
}
|
|
80
93
|
|
|
@@ -83,7 +96,10 @@ class dns_srv_command : public std::enable_shared_from_this<dns_srv_command>
|
|
|
83
96
|
asio::buffer(self->recv_buf_), self->udp_sender_, [self](std::error_code ec2, std::size_t bytes_transferred) mutable {
|
|
84
97
|
self->udp_deadline_.cancel();
|
|
85
98
|
if (ec2) {
|
|
86
|
-
CB_LOG_DEBUG("DNS UDP read operation has got error
|
|
99
|
+
CB_LOG_DEBUG("DNS UDP read operation has got error, retrying with TCP, address=\"{}:{}\", ec={}",
|
|
100
|
+
self->address_.to_string(),
|
|
101
|
+
self->port_,
|
|
102
|
+
ec2.message());
|
|
87
103
|
return self->retry_with_tcp();
|
|
88
104
|
}
|
|
89
105
|
self->recv_buf_.resize(bytes_transferred);
|
|
@@ -104,11 +120,13 @@ class dns_srv_command : public std::enable_shared_from_this<dns_srv_command>
|
|
|
104
120
|
});
|
|
105
121
|
});
|
|
106
122
|
udp_deadline_.expires_after(udp_timeout);
|
|
107
|
-
|
|
123
|
+
udp_deadline_.async_wait([self = shared_from_this()](std::error_code ec) {
|
|
108
124
|
if (ec == asio::error::operation_aborted) {
|
|
109
125
|
return;
|
|
110
126
|
}
|
|
111
|
-
CB_LOG_DEBUG("DNS UDP deadline has been reached, cancelling UDP operation and fall back to TCP"
|
|
127
|
+
CB_LOG_DEBUG("DNS UDP deadline has been reached, cancelling UDP operation and fall back to TCP, address=\"{}:{}\"",
|
|
128
|
+
self->address_.to_string(),
|
|
129
|
+
self->port_);
|
|
112
130
|
self->udp_.cancel();
|
|
113
131
|
return self->retry_with_tcp();
|
|
114
132
|
});
|
|
@@ -118,7 +136,10 @@ class dns_srv_command : public std::enable_shared_from_this<dns_srv_command>
|
|
|
118
136
|
if (ec == asio::error::operation_aborted) {
|
|
119
137
|
return;
|
|
120
138
|
}
|
|
121
|
-
CB_LOG_DEBUG("DNS deadline has been reached, cancelling in-flight operations (tcp.is_open={})",
|
|
139
|
+
CB_LOG_DEBUG("DNS deadline has been reached, cancelling in-flight operations (tcp.is_open={}, address=\"{}:{}\")",
|
|
140
|
+
self->tcp_.is_open(),
|
|
141
|
+
self->address_.to_string(),
|
|
142
|
+
self->port_);
|
|
122
143
|
self->udp_.cancel();
|
|
123
144
|
if (self->tcp_.is_open()) {
|
|
124
145
|
self->tcp_.cancel();
|
|
@@ -140,53 +161,65 @@ class dns_srv_command : public std::enable_shared_from_this<dns_srv_command>
|
|
|
140
161
|
tcp_.async_connect(endpoint, [self = shared_from_this()](std::error_code ec1) mutable {
|
|
141
162
|
if (ec1) {
|
|
142
163
|
self->deadline_.cancel();
|
|
143
|
-
CB_LOG_DEBUG(
|
|
164
|
+
CB_LOG_DEBUG(
|
|
165
|
+
"DNS TCP connection has been aborted, address=\"{}:{}\", ec={}", self->address_.to_string(), self->port_, ec1.message());
|
|
144
166
|
return self->handler_({ ec1 });
|
|
145
167
|
}
|
|
146
168
|
auto send_size = static_cast<std::uint16_t>(self->send_buf_.size());
|
|
147
169
|
self->send_buf_.insert(self->send_buf_.begin(), static_cast<std::uint8_t>(send_size & 0xffU));
|
|
148
170
|
self->send_buf_.insert(self->send_buf_.begin(), static_cast<std::uint8_t>(send_size >> 8U));
|
|
171
|
+
CB_LOG_TRACE(
|
|
172
|
+
"Query DNS-SRV (TCP) address=\"{}:{}\"{:a}", self->address_.to_string(), self->port_, spdlog::to_hex(self->send_buf_));
|
|
149
173
|
asio::async_write(
|
|
150
174
|
self->tcp_, asio::buffer(self->send_buf_), [self](std::error_code ec2, std::size_t /* bytes_transferred */) mutable {
|
|
151
175
|
if (ec2) {
|
|
152
|
-
CB_LOG_DEBUG("DNS TCP write operation has been aborted, {}",
|
|
176
|
+
CB_LOG_DEBUG("DNS TCP write operation has been aborted, address=\"{}:{}\", ec={}",
|
|
177
|
+
self->address_.to_string(),
|
|
178
|
+
self->port_,
|
|
179
|
+
ec2.message());
|
|
153
180
|
self->deadline_.cancel();
|
|
154
181
|
if (ec2 == asio::error::operation_aborted) {
|
|
155
182
|
ec2 = errc::common::unambiguous_timeout;
|
|
156
183
|
}
|
|
157
184
|
return self->handler_({ ec2 });
|
|
158
185
|
}
|
|
159
|
-
asio::async_read(
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
186
|
+
asio::async_read(
|
|
187
|
+
self->tcp_,
|
|
188
|
+
asio::buffer(&self->recv_buf_size_, sizeof(std::uint16_t)),
|
|
189
|
+
[self](std::error_code ec3, std::size_t /* bytes_transferred */) mutable {
|
|
190
|
+
if (ec3) {
|
|
191
|
+
CB_LOG_DEBUG("DNS TCP buf size read operation has been aborted, address=\"{}:{}\", ec={}",
|
|
192
|
+
self->address_.to_string(),
|
|
193
|
+
self->port_,
|
|
194
|
+
ec3.message());
|
|
195
|
+
self->deadline_.cancel();
|
|
196
|
+
return self->handler_({ ec3 });
|
|
197
|
+
}
|
|
198
|
+
self->recv_buf_size_ = utils::byte_swap(self->recv_buf_size_);
|
|
199
|
+
self->recv_buf_.resize(self->recv_buf_size_);
|
|
200
|
+
CB_LOG_DEBUG("DNS TCP schedule read of {} bytes", self->recv_buf_size_);
|
|
201
|
+
asio::async_read(
|
|
202
|
+
self->tcp_, asio::buffer(self->recv_buf_), [self](std::error_code ec4, std::size_t bytes_transferred) mutable {
|
|
203
|
+
self->deadline_.cancel();
|
|
204
|
+
if (ec4) {
|
|
205
|
+
CB_LOG_DEBUG("DNS TCP read operation has been aborted, address=\"{}:{}\", ec={}",
|
|
206
|
+
self->address_.to_string(),
|
|
207
|
+
self->port_,
|
|
208
|
+
ec4.message());
|
|
209
|
+
return self->handler_({ ec4 });
|
|
210
|
+
}
|
|
211
|
+
self->recv_buf_.resize(bytes_transferred);
|
|
212
|
+
const dns_message message = dns_codec::decode(self->recv_buf_);
|
|
213
|
+
dns_srv_response resp{ ec4 };
|
|
214
|
+
resp.targets.reserve(message.answers.size());
|
|
215
|
+
for (const auto& answer : message.answers) {
|
|
216
|
+
resp.targets.emplace_back(
|
|
217
|
+
dns_srv_response::address{ utils::join_strings(answer.target.labels, "."), answer.port });
|
|
218
|
+
}
|
|
219
|
+
CB_LOG_DEBUG("DNS TCP returned {} records", resp.targets.size());
|
|
220
|
+
return self->handler_(std::move(resp));
|
|
221
|
+
});
|
|
222
|
+
});
|
|
190
223
|
});
|
|
191
224
|
});
|
|
192
225
|
}
|
|
@@ -87,7 +87,7 @@ load_resolv_conf()
|
|
|
87
87
|
|
|
88
88
|
if (dns_servers.size() > 0) {
|
|
89
89
|
CB_LOG_DEBUG(
|
|
90
|
-
"Found DNS Servers: [{}],
|
|
90
|
+
"Found DNS Servers: [{}], selected nameserver: \"{}\"", couchbase::core::utils::join_strings(dns_servers, ", "), dns_servers[0]);
|
|
91
91
|
return dns_servers[0];
|
|
92
92
|
}
|
|
93
93
|
CB_LOG_WARNING("Unable to find DNS nameserver");
|
|
@@ -118,13 +118,13 @@ load_resolv_conf(const char* conf_path)
|
|
|
118
118
|
if (space == std::string::npos || space == offset || line.size() < space + 2) {
|
|
119
119
|
continue;
|
|
120
120
|
}
|
|
121
|
-
if (
|
|
121
|
+
if (const auto keyword = line.substr(offset, space); keyword != "nameserver") {
|
|
122
122
|
continue;
|
|
123
123
|
}
|
|
124
124
|
offset = space + 1;
|
|
125
125
|
space = line.find(' ', offset);
|
|
126
|
-
auto nameserver = line.substr(offset, space);
|
|
127
|
-
CB_LOG_DEBUG("
|
|
126
|
+
auto nameserver = (space == std::string::npos) ? line.substr(offset) : line.substr(offset, space - offset);
|
|
127
|
+
CB_LOG_DEBUG("Selected nameserver: \"{}\" from \"{}\"", nameserver, conf_path);
|
|
128
128
|
return nameserver;
|
|
129
129
|
}
|
|
130
130
|
}
|
|
@@ -147,6 +147,7 @@ dns_config::system_config()
|
|
|
147
147
|
std::error_code ec;
|
|
148
148
|
asio::ip::address::from_string(nameserver, ec);
|
|
149
149
|
if (ec) {
|
|
150
|
+
CB_LOG_DEBUG("Unable to parse \"{}\" as a network address, fall back to \"{}\"", nameserver, default_nameserver);
|
|
150
151
|
nameserver = default_nameserver;
|
|
151
152
|
}
|
|
152
153
|
instance.nameserver_ = nameserver;
|
|
@@ -1279,16 +1279,15 @@ class mcbp_session_impl
|
|
|
1279
1279
|
}
|
|
1280
1280
|
last_active_ = std::chrono::steady_clock::now();
|
|
1281
1281
|
if (it != endpoints_.end()) {
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
it->endpoint().port(),
|
|
1286
|
-
origin_.options().connect_timeout.count());
|
|
1282
|
+
auto hostname = it->endpoint().address().to_string();
|
|
1283
|
+
auto port = it->endpoint().port();
|
|
1284
|
+
CB_LOG_DEBUG("{} connecting to {}:{}, timeout={}ms", log_prefix_, hostname, port, origin_.options().connect_timeout.count());
|
|
1287
1285
|
connection_deadline_.expires_after(origin_.options().connect_timeout);
|
|
1288
|
-
connection_deadline_.async_wait([self = shared_from_this()](const auto timer_ec) {
|
|
1286
|
+
connection_deadline_.async_wait([self = shared_from_this(), hostname, port](const auto timer_ec) {
|
|
1289
1287
|
if (timer_ec == asio::error::operation_aborted || self->stopped_) {
|
|
1290
1288
|
return;
|
|
1291
1289
|
}
|
|
1290
|
+
CB_LOG_DEBUG("{} unable to connect to {}:{} in time, reconnecting", self->log_prefix_, hostname, port);
|
|
1292
1291
|
return self->stream_->close([self](std::error_code) { self->initiate_bootstrap(); });
|
|
1293
1292
|
});
|
|
1294
1293
|
stream_->async_connect(it->endpoint(),
|
|
@@ -29,3 +29,9 @@
|
|
|
29
29
|
* couchbase::core::meta::sdk_version() function is available
|
|
30
30
|
*/
|
|
31
31
|
#define COUCHBASE_CXX_CLIENT_HAS_SDK_SEMVER 1
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* couchbase::core::cluster_options and couchbase::security_options support
|
|
35
|
+
* passing TLS trust certificate by value
|
|
36
|
+
*/
|
|
37
|
+
#define COUCHBASE_CXX_CLIENT_CAN_PASS_TLS_TRUST_CERTIFICATE_BY_VALUE 1
|
|
@@ -85,6 +85,17 @@ query_request::encode_to(query_request::encoded_request_type& encoded, http_cont
|
|
|
85
85
|
case couchbase::query_profile::off:
|
|
86
86
|
break;
|
|
87
87
|
}
|
|
88
|
+
if (use_replica.has_value()) {
|
|
89
|
+
if (context.config.supports_read_from_replica()) {
|
|
90
|
+
if (use_replica.value()) {
|
|
91
|
+
body["use_replica"] = "on";
|
|
92
|
+
} else {
|
|
93
|
+
body["use_replica"] = "off";
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
return errc::common::feature_not_available;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
88
99
|
if (max_parallelism) {
|
|
89
100
|
body["max_parallelism"] = std::to_string(max_parallelism.value());
|
|
90
101
|
}
|
|
@@ -91,6 +91,7 @@ struct query_request {
|
|
|
91
91
|
bool flex_index{ false };
|
|
92
92
|
bool preserve_expiry{ false };
|
|
93
93
|
|
|
94
|
+
std::optional<bool> use_replica{};
|
|
94
95
|
std::optional<std::uint64_t> max_parallelism{};
|
|
95
96
|
std::optional<std::uint64_t> scan_cap{};
|
|
96
97
|
std::optional<std::chrono::milliseconds> scan_wait{};
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2020-2021 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 "origin.hxx"
|
|
19
|
+
|
|
20
|
+
#include <fmt/chrono.h>
|
|
21
|
+
#include <fmt/format.h>
|
|
22
|
+
|
|
23
|
+
#include <tao/json.hpp>
|
|
24
|
+
|
|
25
|
+
namespace tao::json
|
|
26
|
+
{
|
|
27
|
+
|
|
28
|
+
template<>
|
|
29
|
+
struct traits<std::chrono::milliseconds> {
|
|
30
|
+
template<template<typename...> class Traits>
|
|
31
|
+
static void assign(tao::json::basic_value<Traits>& v, const std::chrono::milliseconds& o)
|
|
32
|
+
{
|
|
33
|
+
v = fmt::format("{}", o);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
template<>
|
|
38
|
+
struct traits<std::chrono::nanoseconds> {
|
|
39
|
+
template<template<typename...> class Traits>
|
|
40
|
+
static void assign(tao::json::basic_value<Traits>& v, const std::chrono::nanoseconds& o)
|
|
41
|
+
{
|
|
42
|
+
v = fmt::format("{}", o);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
template<>
|
|
47
|
+
struct traits<couchbase::core::tls_verify_mode> {
|
|
48
|
+
template<template<typename...> class Traits>
|
|
49
|
+
static void assign(tao::json::basic_value<Traits>& v, const couchbase::core::tls_verify_mode& o)
|
|
50
|
+
{
|
|
51
|
+
switch (o) {
|
|
52
|
+
case couchbase::core::tls_verify_mode::none:
|
|
53
|
+
v = "none";
|
|
54
|
+
break;
|
|
55
|
+
case couchbase::core::tls_verify_mode::peer:
|
|
56
|
+
v = "peer";
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
template<>
|
|
63
|
+
struct traits<couchbase::core::io::ip_protocol> {
|
|
64
|
+
template<template<typename...> class Traits>
|
|
65
|
+
static void assign(tao::json::basic_value<Traits>& v, const couchbase::core::io::ip_protocol& o)
|
|
66
|
+
{
|
|
67
|
+
switch (o) {
|
|
68
|
+
case couchbase::core::io::ip_protocol::any:
|
|
69
|
+
v = "any";
|
|
70
|
+
break;
|
|
71
|
+
case couchbase::core::io::ip_protocol::force_ipv4:
|
|
72
|
+
v = "force_ipv4";
|
|
73
|
+
break;
|
|
74
|
+
case couchbase::core::io::ip_protocol::force_ipv6:
|
|
75
|
+
v = "force_ipv6";
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
template<>
|
|
82
|
+
struct traits<couchbase::core::io::dns::dns_config> {
|
|
83
|
+
template<template<typename...> class Traits>
|
|
84
|
+
static void assign(tao::json::basic_value<Traits>& v, const couchbase::core::io::dns::dns_config& o)
|
|
85
|
+
{
|
|
86
|
+
v = {
|
|
87
|
+
{ "port", o.port() },
|
|
88
|
+
{ "nameserver", o.nameserver() },
|
|
89
|
+
{ "timeout", o.timeout() },
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
template<>
|
|
95
|
+
struct traits<couchbase::core::tracing::threshold_logging_options> {
|
|
96
|
+
template<template<typename...> class Traits>
|
|
97
|
+
static void assign(tao::json::basic_value<Traits>& v, const couchbase::core::tracing::threshold_logging_options& o)
|
|
98
|
+
{
|
|
99
|
+
v = {
|
|
100
|
+
{ "orphaned_emit_interval", o.orphaned_emit_interval },
|
|
101
|
+
{ "orphaned_sample_size", o.orphaned_sample_size },
|
|
102
|
+
{ "threshold_emit_interval", o.threshold_emit_interval },
|
|
103
|
+
{ "threshold_sample_size", o.threshold_sample_size },
|
|
104
|
+
{ "key_value_threshold", o.key_value_threshold },
|
|
105
|
+
{ "query_threshold", o.query_threshold },
|
|
106
|
+
{ "view_threshold", o.view_threshold },
|
|
107
|
+
{ "search_threshold", o.search_threshold },
|
|
108
|
+
{ "analytics_threshold", o.analytics_threshold },
|
|
109
|
+
{ "management_threshold", o.management_threshold },
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
template<>
|
|
115
|
+
struct traits<couchbase::core::metrics::logging_meter_options> {
|
|
116
|
+
template<template<typename...> class Traits>
|
|
117
|
+
static void assign(tao::json::basic_value<Traits>& v, const couchbase::core::metrics::logging_meter_options& o)
|
|
118
|
+
{
|
|
119
|
+
v = {
|
|
120
|
+
{ "emit_interval", o.emit_interval },
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
template<>
|
|
126
|
+
struct traits<couchbase::durability_level> {
|
|
127
|
+
template<template<typename...> class Traits>
|
|
128
|
+
static void assign(tao::json::basic_value<Traits>& v, const couchbase::durability_level& o)
|
|
129
|
+
{
|
|
130
|
+
switch (o) {
|
|
131
|
+
case couchbase::durability_level::none:
|
|
132
|
+
v = "none";
|
|
133
|
+
break;
|
|
134
|
+
case couchbase::durability_level::majority:
|
|
135
|
+
v = "majority";
|
|
136
|
+
break;
|
|
137
|
+
case couchbase::durability_level::majority_and_persist_to_active:
|
|
138
|
+
v = "majority_and_persist_to_active";
|
|
139
|
+
break;
|
|
140
|
+
case couchbase::durability_level::persist_to_majority:
|
|
141
|
+
v = "persist_to_majority";
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
template<>
|
|
148
|
+
struct traits<couchbase::query_scan_consistency> {
|
|
149
|
+
template<template<typename...> class Traits>
|
|
150
|
+
static void assign(tao::json::basic_value<Traits>& v, const couchbase::query_scan_consistency& o)
|
|
151
|
+
{
|
|
152
|
+
switch (o) {
|
|
153
|
+
case couchbase::query_scan_consistency::not_bounded:
|
|
154
|
+
v = "not_bounded";
|
|
155
|
+
break;
|
|
156
|
+
case couchbase::query_scan_consistency::request_plus:
|
|
157
|
+
v = "request_plus";
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
template<>
|
|
164
|
+
struct traits<couchbase::transactions::transactions_config::built> {
|
|
165
|
+
template<template<typename...> class Traits>
|
|
166
|
+
static void assign(tao::json::basic_value<Traits>& v, const couchbase::transactions::transactions_config::built& o)
|
|
167
|
+
{
|
|
168
|
+
v = {
|
|
169
|
+
{ "expiration_time", o.expiration_time },
|
|
170
|
+
{ "durability_level", o.level },
|
|
171
|
+
{
|
|
172
|
+
"query_config",
|
|
173
|
+
{
|
|
174
|
+
{ "scan_consistency", o.query_config.scan_consistency },
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"cleanup_config",
|
|
179
|
+
{
|
|
180
|
+
{ "cleanup_lost_attempts", o.cleanup_config.cleanup_lost_attempts },
|
|
181
|
+
{ "cleanup_client_attempts", o.cleanup_config.cleanup_client_attempts },
|
|
182
|
+
{ "cleanup_window", o.cleanup_config.cleanup_window },
|
|
183
|
+
{ "collections", tao::json::empty_array },
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
if (const auto& p = o.kv_timeout; p.has_value()) {
|
|
188
|
+
v["key_value_timeout"] = p.value();
|
|
189
|
+
}
|
|
190
|
+
if (const auto& p = o.metadata_collection; p.has_value()) {
|
|
191
|
+
v["metadata_collection"] = {
|
|
192
|
+
{ "bucket", p.value().bucket },
|
|
193
|
+
{ "scope", p.value().scope },
|
|
194
|
+
{ "collection", p.value().collection },
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
for (const auto& c : o.cleanup_config.collections) {
|
|
198
|
+
v["cleanup_config"]["collections"].emplace_back(tao::json::value{
|
|
199
|
+
{ "bucket", c.bucket },
|
|
200
|
+
{ "scope", c.scope },
|
|
201
|
+
{ "collection", c.collection },
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
} // namespace tao::json
|
|
208
|
+
|
|
209
|
+
namespace couchbase::core
|
|
210
|
+
{
|
|
211
|
+
auto
|
|
212
|
+
origin::to_json() const -> std::string
|
|
213
|
+
{
|
|
214
|
+
tao::json::value json = {
|
|
215
|
+
{
|
|
216
|
+
"options",
|
|
217
|
+
{
|
|
218
|
+
{ "bootstrap_timeout", options_.bootstrap_timeout },
|
|
219
|
+
{ "resolve_timeout", options_.resolve_timeout },
|
|
220
|
+
{ "connect_timeout", options_.connect_timeout },
|
|
221
|
+
{ "key_value_timeout", options_.key_value_timeout },
|
|
222
|
+
{ "key_value_durable_timeout", options_.key_value_durable_timeout },
|
|
223
|
+
{ "view_timeout", options_.view_timeout },
|
|
224
|
+
{ "query_timeout", options_.query_timeout },
|
|
225
|
+
{ "analytics_timeout", options_.analytics_timeout },
|
|
226
|
+
{ "search_timeout", options_.search_timeout },
|
|
227
|
+
{ "management_timeout", options_.management_timeout },
|
|
228
|
+
{ "enable_tls", options_.enable_tls },
|
|
229
|
+
{ "trust_certificate", options_.trust_certificate },
|
|
230
|
+
{ "enable_mutation_tokens", options_.enable_mutation_tokens },
|
|
231
|
+
{ "enable_tcp_keep_alive", options_.enable_tcp_keep_alive },
|
|
232
|
+
{ "use_ip_protocol", options_.use_ip_protocol },
|
|
233
|
+
{ "enable_dns_srv", options_.enable_dns_srv },
|
|
234
|
+
{ "dns_config", options_.dns_config },
|
|
235
|
+
{ "show_queries", options_.show_queries },
|
|
236
|
+
{ "enable_unordered_execution", options_.enable_unordered_execution },
|
|
237
|
+
{ "enable_clustermap_notification", options_.enable_clustermap_notification },
|
|
238
|
+
{ "enable_compression", options_.enable_compression },
|
|
239
|
+
{ "enable_tracing", options_.enable_tracing },
|
|
240
|
+
{ "enable_metrics", options_.enable_metrics },
|
|
241
|
+
{ "tcp_keep_alive_interval", options_.tcp_keep_alive_interval },
|
|
242
|
+
{ "config_poll_interval", options_.config_poll_interval },
|
|
243
|
+
{ "config_poll_floor", options_.config_poll_floor },
|
|
244
|
+
{ "config_idle_redial_timeout", options_.config_idle_redial_timeout },
|
|
245
|
+
{ "max_http_connections", options_.max_http_connections },
|
|
246
|
+
{ "idle_http_connection_timeout", options_.idle_http_connection_timeout },
|
|
247
|
+
{ "user_agent_extra", options_.user_agent_extra },
|
|
248
|
+
{ "dump_configuration", options_.dump_configuration },
|
|
249
|
+
{ "disable_mozilla_ca_certificates", options_.disable_mozilla_ca_certificates },
|
|
250
|
+
{ "metrics_options", options_.metrics_options },
|
|
251
|
+
{ "network", options_.network },
|
|
252
|
+
{ "tls_verify", options_.tls_verify },
|
|
253
|
+
{ "tracing_options", options_.tracing_options },
|
|
254
|
+
{ "transactions_options", options_.transactions },
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
{
|
|
259
|
+
tao::json::value nodes = tao::json::empty_array;
|
|
260
|
+
for (const auto& [hostname, port] : nodes_) {
|
|
261
|
+
nodes.emplace_back(tao::json::value{
|
|
262
|
+
{ "hostname", hostname },
|
|
263
|
+
{ "port", port },
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
json["bootstrap_nodes"] = nodes;
|
|
267
|
+
}
|
|
268
|
+
return tao::json::to_string(json);
|
|
269
|
+
}
|
|
270
|
+
} // namespace couchbase::core
|