couchbase 4.2.5 → 4.2.6-dev.1
Sign up to get free protection for your applications and to get access to all the features.
- 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 -13
- 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
|