couchbase 4.2.11 → 4.3.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.
- package/deps/couchbase-cxx-cache/mozilla-ca-bundle.crt +49 -2
- package/deps/couchbase-cxx-cache/mozilla-ca-bundle.sha256 +1 -1
- package/deps/couchbase-cxx-client/core/impl/cluster.cxx +51 -5
- package/deps/couchbase-cxx-client/core/impl/collection.cxx +224 -209
- package/deps/couchbase-cxx-client/core/impl/query_error_context.cxx +2 -2
- package/deps/couchbase-cxx-client/core/impl/query_index_manager.cxx +1 -0
- package/deps/couchbase-cxx-client/core/io/dns_client.cxx +4 -0
- package/deps/couchbase-cxx-client/core/io/dns_config.cxx +15 -4
- package/deps/couchbase-cxx-client/core/io/dns_config.hxx +1 -1
- package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +84 -53
- package/deps/couchbase-cxx-client/core/mcbp/operation_queue.cxx +1 -0
- package/deps/couchbase-cxx-client/core/meta/features.hxx +5 -0
- package/deps/couchbase-cxx-client/core/operations/document_lookup_in_all_replicas.hxx +116 -105
- package/deps/couchbase-cxx-client/core/operations/document_lookup_in_any_replica.hxx +116 -108
- package/deps/couchbase-cxx-client/core/operations/document_search.cxx +97 -81
- package/deps/couchbase-cxx-client/core/operations/document_search.hxx +5 -0
- package/deps/couchbase-cxx-client/core/range_scan_orchestrator_options.hxx +2 -1
- package/deps/couchbase-cxx-client/core/transactions/atr_cleanup_entry.cxx +16 -7
- package/deps/couchbase-cxx-client/core/transactions/attempt_context_impl.cxx +578 -483
- package/deps/couchbase-cxx-client/core/transactions/attempt_context_testing_hooks.cxx +51 -50
- package/deps/couchbase-cxx-client/core/transactions/attempt_context_testing_hooks.hxx +4 -2
- package/deps/couchbase-cxx-client/core/transactions/cleanup_testing_hooks.cxx +6 -6
- package/deps/couchbase-cxx-client/core/transactions/cleanup_testing_hooks.hxx +3 -2
- package/deps/couchbase-cxx-client/core/transactions/internal/transactions_cleanup.hxx +2 -0
- package/deps/couchbase-cxx-client/core/transactions/internal/utils.hxx +5 -1
- package/deps/couchbase-cxx-client/core/transactions/staged_mutation.cxx +222 -179
- package/deps/couchbase-cxx-client/core/transactions/staged_mutation.hxx +23 -12
- package/deps/couchbase-cxx-client/core/transactions/transactions.cxx +61 -24
- package/deps/couchbase-cxx-client/core/transactions/transactions_cleanup.cxx +36 -16
- package/deps/couchbase-cxx-client/core/transactions/utils.cxx +9 -0
- package/deps/couchbase-cxx-client/core/transactions.hxx +40 -7
- package/deps/couchbase-cxx-client/couchbase/cluster.hxx +19 -0
- package/deps/couchbase-cxx-client/couchbase/fork_event.hxx +39 -0
- package/dist/binding.d.ts +8 -0
- package/dist/bindingutilities.d.ts +6 -1
- package/dist/bindingutilities.js +15 -1
- package/dist/bucketmanager.d.ts +0 -12
- package/dist/cluster.d.ts +0 -2
- package/dist/cluster.js +0 -2
- package/dist/collection.d.ts +3 -3
- package/dist/collection.js +3 -1
- package/dist/querytypes.d.ts +0 -2
- package/dist/rangeScan.d.ts +0 -8
- package/dist/rangeScan.js +0 -8
- package/dist/scope.d.ts +0 -5
- package/dist/scope.js +0 -5
- package/dist/scopesearchindexmanager.d.ts +0 -2
- package/dist/scopesearchindexmanager.js +0 -2
- package/dist/searchexecutor.js +3 -1
- package/dist/searchtypes.d.ts +16 -6
- package/dist/searchtypes.js +2 -6
- package/dist/transactions.d.ts +23 -0
- package/dist/transactions.js +16 -10
- package/dist/vectorsearch.d.ts +8 -8
- package/dist/vectorsearch.js +7 -7
- package/package.json +7 -7
- package/src/instance.cpp +11 -1
- package/src/instance.hpp +1 -0
- package/src/jstocbpp_autogen.hpp +8 -0
- package/src/jstocbpp_transactions.hpp +40 -3
- package/src/transactions.cpp +12 -1
- package/tools/gen-bindings-json.py +0 -1
@@ -1,7 +1,7 @@
|
|
1
1
|
##
|
2
2
|
## Bundle of CA Root Certificates
|
3
3
|
##
|
4
|
-
## Certificate data from Mozilla as of:
|
4
|
+
## Certificate data from Mozilla as of: Mon Mar 11 15:25:27 2024 GMT
|
5
5
|
##
|
6
6
|
## This is a bundle of X.509 certificates of public Certificate Authorities
|
7
7
|
## (CA). These were automatically extracted from Mozilla's root certificates
|
@@ -14,7 +14,7 @@
|
|
14
14
|
## Just configure this file as the SSLCACertificateFile.
|
15
15
|
##
|
16
16
|
## Conversion done with mk-ca-bundle.pl version 1.29.
|
17
|
-
## SHA256:
|
17
|
+
## SHA256: 4d96bd539f4719e9ace493757afbe4a23ee8579de1c97fbebc50bba3c12e8c1e
|
18
18
|
##
|
19
19
|
|
20
20
|
|
@@ -3532,3 +3532,50 @@ dVwPaFsdZcJfMw8eD/A7hvWwTruc9+olBdytoptLFwG+Qt81IR2tq670v64fG9PiO/yzcnMcmyiQ
|
|
3532
3532
|
iRM9HcEARwmWmjgb3bHPDcK0RPOWlc4yOo80nOAXx17Org3bhzjlP1v9mxnhMUF6cKojawHhRUzN
|
3533
3533
|
lM47ni3niAIi9G7oyOzWPPO5std3eqx7
|
3534
3534
|
-----END CERTIFICATE-----
|
3535
|
+
|
3536
|
+
Telekom Security TLS ECC Root 2020
|
3537
|
+
==================================
|
3538
|
+
-----BEGIN CERTIFICATE-----
|
3539
|
+
MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQswCQYDVQQGEwJE
|
3540
|
+
RTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMSswKQYDVQQDDCJUZWxl
|
3541
|
+
a29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIwMB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIz
|
3542
|
+
NTk1OVowYzELMAkGA1UEBhMCREUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkg
|
3543
|
+
R21iSDErMCkGA1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqG
|
3544
|
+
SM49AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/OtdKPD/M1
|
3545
|
+
2kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDPf8iAC8GXs7s1J8nCG6NC
|
3546
|
+
MEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6fMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
|
3547
|
+
AQH/BAQDAgEGMAoGCCqGSM49BAMDA2cAMGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZ
|
3548
|
+
Mo7k+5Dck2TOrbRBR2Diz6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdU
|
3549
|
+
ga/sf+Rn27iQ7t0l
|
3550
|
+
-----END CERTIFICATE-----
|
3551
|
+
|
3552
|
+
Telekom Security TLS RSA Root 2023
|
3553
|
+
==================================
|
3554
|
+
-----BEGIN CERTIFICATE-----
|
3555
|
+
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
|
3581
|
+
-----END CERTIFICATE-----
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
1794c1d4f7055b7d02c2170337b61b48a2ef6c90d77e95444fd2596f4cac609f cacert.pem
|
@@ -157,10 +157,30 @@ class cluster_impl : public std::enable_shared_from_this<cluster_impl>
|
|
157
157
|
public:
|
158
158
|
explicit cluster_impl(couchbase::core::cluster core)
|
159
159
|
: core_{ std::move(core) }
|
160
|
-
, transactions_{ std::make_shared<couchbase::core::transactions::transactions>(core_, core_.origin().second.options().transactions) }
|
161
160
|
{
|
162
161
|
}
|
163
162
|
|
163
|
+
explicit cluster_impl(couchbase::core::cluster core, std::shared_ptr<couchbase::core::transactions::transactions> transactions)
|
164
|
+
: core_{ std::move(core) }
|
165
|
+
, transactions_{ transactions }
|
166
|
+
{
|
167
|
+
}
|
168
|
+
|
169
|
+
void initialize_transactions(std::function<void(std::error_code)>&& handler)
|
170
|
+
{
|
171
|
+
return core::transactions::transactions::create(
|
172
|
+
core_,
|
173
|
+
core_.origin().second.options().transactions,
|
174
|
+
[self = shared_from_this(), handler = std::move(handler)](auto ec, auto txns) mutable {
|
175
|
+
if (ec) {
|
176
|
+
return handler(ec);
|
177
|
+
}
|
178
|
+
|
179
|
+
self->transactions_ = txns;
|
180
|
+
handler({});
|
181
|
+
});
|
182
|
+
}
|
183
|
+
|
164
184
|
void query(std::string statement, query_options::built options, query_handler&& handler) const
|
165
185
|
{
|
166
186
|
return core_.execute(
|
@@ -214,6 +234,13 @@ class cluster_impl : public std::enable_shared_from_this<cluster_impl>
|
|
214
234
|
});
|
215
235
|
}
|
216
236
|
|
237
|
+
void notify_fork(fork_event event)
|
238
|
+
{
|
239
|
+
if (transactions_) {
|
240
|
+
transactions_->notify_fork(event);
|
241
|
+
}
|
242
|
+
}
|
243
|
+
|
217
244
|
void close(core::utils::movable_function<void()> handler)
|
218
245
|
{
|
219
246
|
if (transactions_) {
|
@@ -258,6 +285,11 @@ cluster::cluster(core::cluster core)
|
|
258
285
|
{
|
259
286
|
}
|
260
287
|
|
288
|
+
cluster::cluster(core::cluster core, std::shared_ptr<core::transactions::transactions> transactions)
|
289
|
+
: impl_{ std::make_shared<cluster_impl>(std::move(core), transactions) }
|
290
|
+
{
|
291
|
+
}
|
292
|
+
|
261
293
|
void
|
262
294
|
cluster::query(std::string statement, const query_options& options, query_handler&& handler) const
|
263
295
|
{
|
@@ -361,9 +393,8 @@ cluster::connect(asio::io_context& io, const std::string& connection_string, con
|
|
361
393
|
-> std::future<std::pair<cluster, std::error_code>>
|
362
394
|
{
|
363
395
|
auto barrier = std::make_shared<std::promise<std::pair<cluster, std::error_code>>>();
|
364
|
-
auto
|
365
|
-
|
366
|
-
return future;
|
396
|
+
connect(io, connection_string, options, [barrier](auto c, auto ec) mutable { barrier->set_value({ std::move(c), ec }); });
|
397
|
+
return barrier->get_future();
|
367
398
|
}
|
368
399
|
|
369
400
|
void
|
@@ -378,10 +409,25 @@ cluster::connect(asio::io_context& io,
|
|
378
409
|
if (ec) {
|
379
410
|
return handler({}, ec);
|
380
411
|
}
|
381
|
-
|
412
|
+
auto cluster = couchbase::cluster(std::move(core));
|
413
|
+
return cluster.impl_->initialize_transactions([cluster, handler = std::move(handler)](std::error_code ec) mutable {
|
414
|
+
if (ec) {
|
415
|
+
return cluster.impl_->close([ec, handler = std::move(handler)]() mutable { return handler({}, ec); });
|
416
|
+
}
|
417
|
+
return handler(cluster, ec);
|
418
|
+
});
|
382
419
|
});
|
383
420
|
}
|
384
421
|
|
422
|
+
auto
|
423
|
+
cluster::notify_fork(fork_event event) -> void
|
424
|
+
{
|
425
|
+
if (!impl_) {
|
426
|
+
return;
|
427
|
+
}
|
428
|
+
return impl_->notify_fork(event);
|
429
|
+
}
|
430
|
+
|
385
431
|
auto
|
386
432
|
cluster::close() const -> void
|
387
433
|
{
|
@@ -475,120 +475,129 @@ class collection_impl : public std::enable_shared_from_this<collection_impl>
|
|
475
475
|
{
|
476
476
|
auto request = std::make_shared<couchbase::core::impl::lookup_in_all_replicas_request>(
|
477
477
|
bucket_name_, scope_name_, name_, std::move(document_key), specs, options.timeout);
|
478
|
-
core_.
|
478
|
+
core_.open_bucket(
|
479
479
|
bucket_name_,
|
480
|
-
[core = core_, r = std::move(request), h = std::move(handler)](std::error_code ec
|
481
|
-
const core::topology::configuration& config) mutable {
|
482
|
-
if (!config.capabilities.supports_subdoc_read_replica()) {
|
483
|
-
ec = errc::common::feature_not_available;
|
484
|
-
}
|
485
|
-
|
480
|
+
[core = core_, bucket_name = bucket_name_, r = std::move(request), h = std::move(handler)](std::error_code ec) mutable {
|
486
481
|
if (ec) {
|
487
|
-
|
488
|
-
|
482
|
+
h(core::make_subdocument_error_context(make_key_value_error_context(ec, r->id()), ec, {}, {}, false),
|
483
|
+
lookup_in_all_replicas_result{});
|
484
|
+
return;
|
489
485
|
}
|
490
|
-
struct replica_context {
|
491
|
-
replica_context(core::impl::movable_lookup_in_all_replicas_handler handler, std::uint32_t expected_responses)
|
492
|
-
: handler_(std::move(handler))
|
493
|
-
, expected_responses_(expected_responses)
|
494
|
-
{
|
495
|
-
}
|
496
486
|
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
auto ctx = std::make_shared<replica_context>(std::move(h), config.num_replicas.value_or(0U) + 1U);
|
487
|
+
return core.with_bucket_configuration(
|
488
|
+
bucket_name,
|
489
|
+
[core = core, r = std::move(r), h = std::move(h)](std::error_code ec, const core::topology::configuration& config) mutable {
|
490
|
+
if (!config.capabilities.supports_subdoc_read_replica()) {
|
491
|
+
ec = errc::common::feature_not_available;
|
492
|
+
}
|
504
493
|
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
494
|
+
if (ec) {
|
495
|
+
return h(core::make_subdocument_error_context(make_key_value_error_context(ec, r->id()), ec, {}, {}, false),
|
496
|
+
lookup_in_all_replicas_result{});
|
497
|
+
}
|
498
|
+
struct replica_context {
|
499
|
+
replica_context(core::impl::movable_lookup_in_all_replicas_handler handler, std::uint32_t expected_responses)
|
500
|
+
: handler_(std::move(handler))
|
501
|
+
, expected_responses_(expected_responses)
|
502
|
+
{
|
503
|
+
}
|
504
|
+
|
505
|
+
core::impl::movable_lookup_in_all_replicas_handler handler_;
|
506
|
+
std::uint32_t expected_responses_;
|
507
|
+
bool done_{ false };
|
508
|
+
std::mutex mutex_{};
|
509
|
+
lookup_in_all_replicas_result result_{};
|
510
|
+
};
|
511
|
+
auto ctx = std::make_shared<replica_context>(std::move(h), config.num_replicas.value_or(0U) + 1U);
|
512
|
+
|
513
|
+
for (std::size_t idx = 1U; idx <= config.num_replicas.value_or(0U); ++idx) {
|
514
|
+
core::document_id replica_id{ r->id() };
|
515
|
+
replica_id.node_index(idx);
|
516
|
+
core.execute(core::impl::lookup_in_replica_request{ std::move(replica_id), r->specs(), r->timeout() },
|
517
|
+
[ctx](core::impl::lookup_in_replica_response&& resp) {
|
518
|
+
core::impl::movable_lookup_in_all_replicas_handler local_handler{};
|
519
|
+
{
|
520
|
+
const std::scoped_lock lock(ctx->mutex_);
|
521
|
+
if (ctx->done_) {
|
522
|
+
return;
|
523
|
+
}
|
524
|
+
--ctx->expected_responses_;
|
525
|
+
if (resp.ctx.ec()) {
|
526
|
+
if (ctx->expected_responses_ > 0) {
|
527
|
+
// just ignore the response
|
528
|
+
return;
|
529
|
+
}
|
530
|
+
} else {
|
531
|
+
std::vector<lookup_in_replica_result::entry> entries{};
|
532
|
+
for (const auto& field : resp.fields) {
|
533
|
+
lookup_in_replica_result::entry lookup_in_entry{};
|
534
|
+
lookup_in_entry.path = field.path;
|
535
|
+
lookup_in_entry.value = field.value;
|
536
|
+
lookup_in_entry.exists = field.exists;
|
537
|
+
lookup_in_entry.original_index = field.original_index;
|
538
|
+
lookup_in_entry.ec = field.ec;
|
539
|
+
entries.emplace_back(lookup_in_entry);
|
540
|
+
}
|
541
|
+
ctx->result_.emplace_back(resp.cas, entries, resp.deleted, true /* replica */);
|
542
|
+
}
|
543
|
+
if (ctx->expected_responses_ == 0) {
|
544
|
+
ctx->done_ = true;
|
545
|
+
std::swap(local_handler, ctx->handler_);
|
546
|
+
}
|
547
|
+
}
|
548
|
+
if (local_handler) {
|
549
|
+
if (!ctx->result_.empty()) {
|
550
|
+
resp.ctx.override_ec({});
|
551
|
+
}
|
552
|
+
return local_handler(std::move(resp.ctx), std::move(ctx->result_));
|
553
|
+
}
|
554
|
+
});
|
555
|
+
}
|
548
556
|
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
557
|
+
core::operations::lookup_in_request active{ core::document_id{ r->id() } };
|
558
|
+
active.specs = r->specs();
|
559
|
+
active.timeout = r->timeout();
|
560
|
+
core.execute(active, [ctx](core::operations::lookup_in_response&& resp) {
|
561
|
+
core::impl::movable_lookup_in_all_replicas_handler local_handler{};
|
562
|
+
{
|
563
|
+
const std::scoped_lock lock(ctx->mutex_);
|
564
|
+
if (ctx->done_) {
|
565
|
+
return;
|
566
|
+
}
|
567
|
+
--ctx->expected_responses_;
|
568
|
+
if (resp.ctx.ec()) {
|
569
|
+
if (ctx->expected_responses_ > 0) {
|
570
|
+
// just ignore the response
|
571
|
+
return;
|
572
|
+
}
|
573
|
+
} else {
|
574
|
+
std::vector<lookup_in_replica_result::entry> entries{};
|
575
|
+
for (const auto& field : resp.fields) {
|
576
|
+
lookup_in_replica_result::entry lookup_in_entry{};
|
577
|
+
lookup_in_entry.path = field.path;
|
578
|
+
lookup_in_entry.value = field.value;
|
579
|
+
lookup_in_entry.exists = field.exists;
|
580
|
+
lookup_in_entry.original_index = field.original_index;
|
581
|
+
lookup_in_entry.ec = field.ec;
|
582
|
+
entries.emplace_back(lookup_in_entry);
|
583
|
+
}
|
584
|
+
ctx->result_.emplace_back(resp.cas, entries, resp.deleted, false /* active */);
|
585
|
+
}
|
586
|
+
if (ctx->expected_responses_ == 0) {
|
587
|
+
ctx->done_ = true;
|
588
|
+
std::swap(local_handler, ctx->handler_);
|
589
|
+
}
|
590
|
+
}
|
591
|
+
if (local_handler) {
|
592
|
+
if (!ctx->result_.empty()) {
|
593
|
+
resp.ctx.override_ec({});
|
594
|
+
}
|
595
|
+
return local_handler(std::move(resp.ctx), std::move(ctx->result_));
|
596
|
+
}
|
597
|
+
});
|
598
|
+
});
|
590
599
|
});
|
591
|
-
}
|
600
|
+
};
|
592
601
|
|
593
602
|
void lookup_in_any_replica(std::string document_key,
|
594
603
|
const std::vector<core::impl::subdoc::command>& specs,
|
@@ -597,114 +606,120 @@ class collection_impl : public std::enable_shared_from_this<collection_impl>
|
|
597
606
|
{
|
598
607
|
auto request = std::make_shared<couchbase::core::impl::lookup_in_any_replica_request>(
|
599
608
|
bucket_name_, scope_name_, name_, std::move(document_key), specs, options.timeout);
|
600
|
-
core_.
|
609
|
+
core_.open_bucket(
|
601
610
|
bucket_name_,
|
602
|
-
[core = core_, r = std::move(request), h = std::move(handler)](std::error_code ec
|
603
|
-
const core::topology::configuration& config) mutable {
|
604
|
-
if (!config.capabilities.supports_subdoc_read_replica()) {
|
605
|
-
ec = errc::common::feature_not_available;
|
606
|
-
}
|
607
|
-
if (r->specs().size() > 16) {
|
608
|
-
ec = errc::common::invalid_argument;
|
609
|
-
}
|
611
|
+
[core = core_, bucket_name = bucket_name_, r = std::move(request), h = std::move(handler)](std::error_code ec) mutable {
|
610
612
|
if (ec) {
|
611
|
-
|
612
|
-
|
613
|
+
h(core::make_subdocument_error_context(make_key_value_error_context(ec, r->id()), ec, {}, {}, false),
|
614
|
+
lookup_in_replica_result{});
|
615
|
+
return;
|
613
616
|
}
|
614
|
-
struct replica_context {
|
615
|
-
replica_context(core::impl::movable_lookup_in_any_replica_handler handler, std::uint32_t expected_responses)
|
616
|
-
: handler_(std::move(handler))
|
617
|
-
, expected_responses_(expected_responses)
|
618
|
-
{
|
619
|
-
}
|
620
617
|
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
618
|
+
return core.with_bucket_configuration(
|
619
|
+
bucket_name,
|
620
|
+
[core = core, r = std::move(r), h = std::move(h)](std::error_code ec, const core::topology::configuration& config) mutable {
|
621
|
+
if (!config.capabilities.supports_subdoc_read_replica()) {
|
622
|
+
ec = errc::common::feature_not_available;
|
623
|
+
}
|
624
|
+
if (ec) {
|
625
|
+
return h(core::make_subdocument_error_context(make_key_value_error_context(ec, r->id()), ec, {}, {}, false),
|
626
|
+
lookup_in_replica_result{});
|
627
|
+
}
|
628
|
+
struct replica_context {
|
629
|
+
replica_context(core::impl::movable_lookup_in_any_replica_handler handler, std::uint32_t expected_responses)
|
630
|
+
: handler_(std::move(handler))
|
631
|
+
, expected_responses_(expected_responses)
|
632
|
+
{
|
633
|
+
}
|
634
|
+
|
635
|
+
core::impl::movable_lookup_in_any_replica_handler handler_;
|
636
|
+
std::uint32_t expected_responses_;
|
637
|
+
bool done_{ false };
|
638
|
+
std::mutex mutex_{};
|
639
|
+
};
|
640
|
+
auto ctx = std::make_shared<replica_context>(std::move(h), config.num_replicas.value_or(0U) + 1U);
|
641
|
+
|
642
|
+
for (std::size_t idx = 1U; idx <= config.num_replicas.value_or(0U); ++idx) {
|
643
|
+
core::document_id replica_id{ r->id() };
|
644
|
+
replica_id.node_index(idx);
|
645
|
+
core.execute(core::impl::lookup_in_replica_request{ std::move(replica_id), r->specs(), r->timeout() },
|
646
|
+
[ctx](core::impl::lookup_in_replica_response&& resp) {
|
647
|
+
core::impl::movable_lookup_in_any_replica_handler local_handler;
|
648
|
+
{
|
649
|
+
const std::scoped_lock lock(ctx->mutex_);
|
650
|
+
if (ctx->done_) {
|
651
|
+
return;
|
652
|
+
}
|
653
|
+
--ctx->expected_responses_;
|
654
|
+
if (resp.ctx.ec()) {
|
655
|
+
if (ctx->expected_responses_ > 0) {
|
656
|
+
// just ignore the response
|
657
|
+
return;
|
658
|
+
}
|
659
|
+
// consider document irretrievable and give up
|
660
|
+
resp.ctx.override_ec(errc::key_value::document_irretrievable);
|
661
|
+
}
|
662
|
+
ctx->done_ = true;
|
663
|
+
std::swap(local_handler, ctx->handler_);
|
664
|
+
}
|
665
|
+
if (local_handler) {
|
666
|
+
std::vector<lookup_in_replica_result::entry> entries;
|
667
|
+
for (const auto& field : resp.fields) {
|
668
|
+
lookup_in_replica_result::entry entry{};
|
669
|
+
entry.path = field.path;
|
670
|
+
entry.original_index = field.original_index;
|
671
|
+
entry.exists = field.exists;
|
672
|
+
entry.value = field.value;
|
673
|
+
entry.ec = field.ec;
|
674
|
+
entries.emplace_back(entry);
|
675
|
+
}
|
676
|
+
return local_handler(
|
677
|
+
std::move(resp.ctx),
|
678
|
+
lookup_in_replica_result{ resp.cas, entries, resp.deleted, true /* replica */ });
|
679
|
+
}
|
680
|
+
});
|
681
|
+
}
|
668
682
|
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
683
|
+
core::operations::lookup_in_request active{ core::document_id{ r->id() } };
|
684
|
+
active.specs = r->specs();
|
685
|
+
active.timeout = r->timeout();
|
686
|
+
core.execute(active, [ctx](core::operations::lookup_in_response&& resp) {
|
687
|
+
core::impl::movable_lookup_in_any_replica_handler local_handler{};
|
688
|
+
{
|
689
|
+
const std::scoped_lock lock(ctx->mutex_);
|
690
|
+
if (ctx->done_) {
|
691
|
+
return;
|
692
|
+
}
|
693
|
+
--ctx->expected_responses_;
|
694
|
+
if (resp.ctx.ec()) {
|
695
|
+
if (ctx->expected_responses_ > 0) {
|
696
|
+
// just ignore the response
|
697
|
+
return;
|
698
|
+
}
|
699
|
+
// consider document irretrievable and give up
|
700
|
+
resp.ctx.override_ec(errc::key_value::document_irretrievable);
|
701
|
+
}
|
702
|
+
ctx->done_ = true;
|
703
|
+
std::swap(local_handler, ctx->handler_);
|
704
|
+
}
|
705
|
+
if (local_handler) {
|
706
|
+
std::vector<lookup_in_replica_result::entry> entries;
|
707
|
+
for (const auto& field : resp.fields) {
|
708
|
+
lookup_in_replica_result::entry entry{};
|
709
|
+
entry.path = field.path;
|
710
|
+
entry.original_index = field.original_index;
|
711
|
+
entry.exists = field.exists;
|
712
|
+
entry.value = field.value;
|
713
|
+
entry.ec = field.ec;
|
714
|
+
entries.emplace_back(entry);
|
715
|
+
}
|
716
|
+
return local_handler(std::move(resp.ctx),
|
717
|
+
lookup_in_replica_result{ resp.cas, entries, resp.deleted, false /* active */ });
|
718
|
+
}
|
719
|
+
});
|
720
|
+
});
|
706
721
|
});
|
707
|
-
}
|
722
|
+
};
|
708
723
|
|
709
724
|
void mutate_in(std::string document_key,
|
710
725
|
const std::vector<core::impl::subdoc::command>& specs,
|