couchbase 4.2.11 → 4.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBjMQswCQYDVQQG
|
3556
|
+
EwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMSswKQYDVQQDDCJU
|
3557
|
+
ZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAyMDIzMB4XDTIzMDMyODEyMTY0NVoXDTQ4MDMy
|
3558
|
+
NzIzNTk1OVowYzELMAkGA1UEBhMCREUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJp
|
3559
|
+
dHkgR21iSDErMCkGA1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgUlNBIFJvb3QgMjAyMzCCAiIw
|
3560
|
+
DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAO01oYGA88tKaVvC+1GDrib94W7zgRJ9cUD/h3VC
|
3561
|
+
KSHtgVIs3xLBGYSJwb3FKNXVS2xE1kzbB5ZKVXrKNoIENqil/Cf2SfHVcp6R+SPWcHu79ZvB7JPP
|
3562
|
+
GeplfohwoHP89v+1VmLhc2o0mD6CuKyVU/QBoCcHcqMAU6DksquDOFczJZSfvkgdmOGjup5czQRx
|
3563
|
+
UX11eKvzWarE4GC+j4NSuHUaQTXtvPM6Y+mpFEXX5lLRbtLevOP1Czvm4MS9Q2QTps70mDdsipWo
|
3564
|
+
l8hHD/BeEIvnHRz+sTugBTNoBUGCwQMrAcjnj02r6LX2zWtEtefdi+zqJbQAIldNsLGyMcEWzv/9
|
3565
|
+
FIS3R/qy8XDe24tsNlikfLMR0cN3f1+2JeANxdKz+bi4d9s3cXFH42AYTyS2dTd4uaNir73Jco4v
|
3566
|
+
zLuu2+QVUhkHM/tqty1LkCiCc/4YizWN26cEar7qwU02OxY2kTLvtkCJkUPg8qKrBC7m8kwOFjQg
|
3567
|
+
rIfBLX7JZkcXFBGk8/ehJImr2BrIoVyxo/eMbcgByU/J7MT8rFEz0ciD0cmfHdRHNCk+y7AO+oML
|
3568
|
+
KFjlKdw/fKifybYKu6boRhYPluV75Gp6SG12mAWl3G0eQh5C2hrgUve1g8Aae3g1LDj1H/1Joy7S
|
3569
|
+
WWO/gLCMk3PLNaaZlSJhZQNg+y+TS/qanIA7AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAdBgNV
|
3570
|
+
HQ4EFgQUtqeXgj10hZv3PJ+TmpV5dVKMbUcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS2
|
3571
|
+
p5eCPXSFm/c8n5OalXl1UoxtRzANBgkqhkiG9w0BAQwFAAOCAgEAqMxhpr51nhVQpGv7qHBFfLp+
|
3572
|
+
sVr8WyP6Cnf4mHGCDG3gXkaqk/QeoMPhk9tLrbKmXauw1GLLXrtm9S3ul0A8Yute1hTWjOKWi0Fp
|
3573
|
+
kzXmuZlrYrShF2Y0pmtjxrlO8iLpWA1WQdH6DErwM807u20hOq6OcrXDSvvpfeWxm4bu4uB9tPcy
|
3574
|
+
/SKE8YXJN3nptT+/XOR0so8RYgDdGGah2XsjX/GO1WfoVNpbOms2b/mBsTNHM3dA+VKq3dSDz4V4
|
3575
|
+
mZqTuXNnQkYRIer+CqkbGmVps4+uFrb2S1ayLfmlyOw7YqPta9BO1UAJpB+Y1zqlklkg5LB9zVtz
|
3576
|
+
aL1txKITDmcZuI1CfmwMmm6gJC3VRRvcxAIU/oVbZZfKTpBQCHpCNfnqwmbU+AGuHrS+w6jv/naa
|
3577
|
+
oqYfRvaE7fzbzsQCzndILIyy7MMAo+wsVRjBfhnu4S/yrYObnqsZ38aKL4x35bcF7DvB7L6Gs4a8
|
3578
|
+
wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+ljX273CXE2whJdV/LItM3z7gLfEdxquVeE
|
3579
|
+
HVlNjM7IDiPCtyaaEBRx/pOyiriA8A4QntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0
|
3580
|
+
o82bNSQ3+pCTE4FCxpgmdTdmQRCsu/WU48IxK63nI1bMNSWSs1A=
|
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,
|