Skip to content

Commit 4e0059f

Browse files
committed
CXXCBC-745: Implement lazy connections mode
Do not rush to open KV connections after the first configuration has been received. Instead wait for the first operation that would be mapped to the socket.
1 parent b2a579c commit 4e0059f

File tree

4 files changed

+78
-2
lines changed

4 files changed

+78
-2
lines changed

core/bucket.cxx

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "collection_id_cache_entry.hxx"
2121
#include "core/app_telemetry_meter.hxx"
22+
#include "core/cluster_options.hxx"
2223
#include "core/config_listener.hxx"
2324
#include "core/document_id.hxx"
2425
#include "core/error_context/key_value_error_map_info.hxx"
@@ -319,11 +320,11 @@ class bucket_impl
319320
{
320321
if (req->key_.empty()) {
321322
if (auto server = server_by_vbucket(req->vbucket_, req->replica_index_); server) {
322-
return find_session_by_index(server.value());
323+
return find_or_connect_session_by_index(server.value());
323324
}
324325
} else if (auto [partition, server] = map_id(req->key_, req->replica_index_); server) {
325326
req->vbucket_ = partition;
326-
return find_session_by_index(server.value());
327+
return find_or_connect_session_by_index(server.value());
327328
}
328329
return std::nullopt;
329330
}
@@ -367,6 +368,53 @@ class bucket_impl
367368
return { 0, std::nullopt };
368369
}
369370

371+
void connect_session(std::size_t index)
372+
{
373+
const std::scoped_lock lock(config_mutex_, sessions_mutex_);
374+
if (!config_) {
375+
return;
376+
}
377+
378+
const auto& node = config_->nodes[index];
379+
380+
const auto& hostname = node.hostname_for(origin_.options().network);
381+
auto port = node.port_or(
382+
origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0);
383+
if (port == 0) {
384+
return;
385+
}
386+
387+
const couchbase::core::origin origin(origin_.credentials(), hostname, port, origin_.options());
388+
io::mcbp_session session =
389+
origin_.options().enable_tls
390+
? io::mcbp_session(
391+
client_id_, node.node_uuid, ctx_, tls_, origin, state_listener_, name_, known_features_)
392+
: io::mcbp_session(
393+
client_id_, node.node_uuid, ctx_, origin, state_listener_, name_, known_features_);
394+
CB_LOG_DEBUG(R"({} rev={}, connect idx={}, session="{}", address="{}:{}")",
395+
log_prefix_,
396+
config_->rev_str(),
397+
node.index,
398+
session.id(),
399+
hostname,
400+
port);
401+
session.bootstrap(
402+
[self = shared_from_this(), session](std::error_code err,
403+
topology::configuration cfg) mutable -> void {
404+
if (err) {
405+
return self->remove_session(session.id());
406+
}
407+
self->update_config(std::move(cfg));
408+
session.on_configuration_update(self);
409+
session.on_stop([id = session.id(), self]() -> void {
410+
self->remove_session(id);
411+
});
412+
self->drain_deferred_queue({});
413+
},
414+
true);
415+
sessions_.insert_or_assign(index, std::move(session));
416+
}
417+
370418
void restart_sessions()
371419
{
372420
const std::scoped_lock lock(config_mutex_, sessions_mutex_);
@@ -812,6 +860,10 @@ class bucket_impl
812860
continue;
813861
}
814862

863+
if (origin_.options().enable_lazy_connections) {
864+
++next_index;
865+
continue;
866+
}
815867
const couchbase::core::origin origin(
816868
origin_.credentials(), hostname, port, origin_.options());
817869
io::mcbp_session session =
@@ -885,6 +937,16 @@ class bucket_impl
885937
return {};
886938
}
887939

940+
[[nodiscard]] auto find_or_connect_session_by_index(std::size_t index)
941+
-> std::optional<io::mcbp_session>
942+
{
943+
if (auto session = find_session_by_index(index); session) {
944+
return session;
945+
}
946+
connect_session(index);
947+
return {};
948+
}
949+
888950
[[nodiscard]] auto next_session_index() -> std::size_t
889951
{
890952
const std::scoped_lock lock(sessions_mutex_);
@@ -1206,4 +1268,10 @@ bucket::direct_re_queue(const std::shared_ptr<mcbp::queue_request>& req, bool is
12061268
{
12071269
return impl_->direct_re_queue(req, is_retry);
12081270
}
1271+
1272+
void
1273+
bucket::connect_session(std::size_t index)
1274+
{
1275+
return impl_->connect_session(index);
1276+
}
12091277
} // namespace couchbase::core

core/bucket.hxx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ public:
105105
});
106106
}
107107

108+
void connect_session(std::size_t index);
109+
108110
template<typename Request>
109111
void map_and_send(std::shared_ptr<operations::mcbp_command<bucket, Request>> cmd)
110112
{
@@ -142,6 +144,9 @@ public:
142144
session.has_value() ? session->bootstrap_address() : "",
143145
session.has_value() && session->has_config(),
144146
config_rev());
147+
if (!session) {
148+
connect_session(index);
149+
}
145150
return defer_command([self = shared_from_this(), cmd](std::error_code ec) {
146151
if (ec == errc::common::request_canceled) {
147152
return cmd->cancel(retry_reason::do_not_retry);

core/cluster_options.hxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ public:
113113
};
114114
bool preserve_bootstrap_nodes_order{ false };
115115
bool allow_enterprise_analytics{ false };
116+
bool enable_lazy_connections{ false };
116117
};
117118

118119
} // namespace couchbase::core

core/utils/connection_string.cxx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,8 @@ extract_options(connection_string& connstr)
590590
parse_option(connstr.options.preserve_bootstrap_nodes_order, name, value, connstr.warnings);
591591
} else if (name == "allow_enterprise_analytics") {
592592
parse_option(connstr.options.allow_enterprise_analytics, name, value, connstr.warnings);
593+
} else if (name == "enable_lazy_connections") {
594+
parse_option(connstr.options.enable_lazy_connections, name, value, connstr.warnings);
593595
} else {
594596
connstr.warnings.push_back(
595597
fmt::format(R"(unknown parameter "{}" in connection string (value "{}"))", name, value));

0 commit comments

Comments
 (0)