couchbase 4.2.11-rc.1 → 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/CMakeLists.txt +1 -0
- package/deps/couchbase-cxx-client/cmake/ThirdPartyDependencies.cmake +2 -0
- package/deps/couchbase-cxx-client/core/bucket.cxx +2 -2
- 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 +95 -53
- package/deps/couchbase-cxx-client/core/io/mcbp_session.hxx +1 -0
- 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_load_balancer.cxx +141 -0
- package/deps/couchbase-cxx-client/core/range_scan_load_balancer.hxx +64 -0
- package/deps/couchbase-cxx-client/core/range_scan_orchestrator.cxx +224 -336
- package/deps/couchbase-cxx-client/core/range_scan_orchestrator.hxx +5 -6
- package/deps/couchbase-cxx-client/core/range_scan_orchestrator_options.hxx +8 -5
- package/deps/couchbase-cxx-client/core/scan_result.hxx +1 -11
- 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/bucket.hxx +2 -2
- package/deps/couchbase-cxx-client/couchbase/cluster.hxx +20 -1
- package/deps/couchbase-cxx-client/couchbase/collection.hxx +1 -0
- package/deps/couchbase-cxx-client/couchbase/collection_query_index_manager.hxx +1 -1
- package/deps/couchbase-cxx-client/couchbase/error_context.hxx +1 -0
- package/deps/couchbase-cxx-client/couchbase/fork_event.hxx +39 -0
- package/deps/couchbase-cxx-client/couchbase/get_links_analytics_options.hxx +2 -2
- package/deps/couchbase-cxx-client/couchbase/scope.hxx +1 -1
- package/deps/couchbase-cxx-client/couchbase/search_options.hxx +2 -2
- package/deps/couchbase-cxx-client/couchbase/search_result.hxx +1 -1
- package/deps/couchbase-cxx-client/couchbase/subdocument_error_context.hxx +1 -0
- package/deps/couchbase-cxx-client/couchbase/transactions/transaction_options.hxx +1 -1
- package/deps/couchbase-cxx-client/couchbase-sdk-cxx-black-duck-manifest.yaml +1 -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 -1
- package/src/jstocbpp_transactions.hpp +40 -3
- package/src/transactions.cpp +12 -1
- package/tools/gen-bindings-json.py +0 -1
- package/deps/couchbase-cxx-client/core/scan_options.hxx +0 -44
@@ -17,6 +17,7 @@
|
|
17
17
|
#include "staged_mutation.hxx"
|
18
18
|
|
19
19
|
#include "attempt_context_impl.hxx"
|
20
|
+
#include "attempt_context_testing_hooks.hxx"
|
20
21
|
#include "core/cluster.hxx"
|
21
22
|
|
22
23
|
#include "internal/transaction_fields.hxx"
|
@@ -357,98 +358,94 @@ staged_mutation_queue::rollback(attempt_context_impl* ctx)
|
|
357
358
|
void
|
358
359
|
staged_mutation_queue::rollback_insert(attempt_context_impl* ctx,
|
359
360
|
const staged_mutation& item,
|
360
|
-
async_exp_delay delay,
|
361
|
+
async_exp_delay& delay,
|
361
362
|
utils::movable_function<void(std::exception_ptr)> callback)
|
362
363
|
{
|
363
364
|
CB_ATTEMPT_CTX_LOG_TRACE(ctx, "rolling back staged insert for {} with cas {}", item.doc().id(), item.doc().cas().value());
|
364
365
|
|
365
366
|
asio::post(asio::bind_executor(ctx->cluster_ref().io_context(), [this, callback = std::move(callback), ctx, &item, delay]() mutable {
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
throw client_error(*ec, "expired in rollback and not in overtime mode");
|
370
|
-
}
|
371
|
-
ec = ctx->hooks_.before_rollback_delete_inserted(ctx, item.doc().id().key());
|
372
|
-
if (ec) {
|
373
|
-
throw client_error(*ec, "before_rollback_delete_insert hook threw error");
|
367
|
+
auto handler = [this, callback = std::move(callback), ctx, &item, delay](const std::optional<client_error>& e) mutable {
|
368
|
+
if (e) {
|
369
|
+
return handle_rollback_insert_error(e.value(), ctx, item, delay, std::move(callback));
|
374
370
|
}
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
req.access_deleted = true;
|
382
|
-
req.cas = item.doc().cas();
|
383
|
-
wrap_durable_request(req, ctx->overall().config());
|
384
|
-
return ctx->cluster_ref().execute(
|
385
|
-
req, [this, callback = std::move(callback), ctx, &item, delay](const core::operations::mutate_in_response& resp) mutable {
|
386
|
-
CB_ATTEMPT_CTX_LOG_TRACE(ctx, "mutate_in for {} with cas {}", item.doc().id(), item.doc().cas().value());
|
387
|
-
|
388
|
-
auto res = result::create_from_subdoc_response(resp);
|
389
|
-
try {
|
390
|
-
validate_rollback_insert_result(ctx, res, item);
|
391
|
-
} catch (const client_error& e) {
|
392
|
-
handle_rollback_insert_error(e, ctx, item, delay, std::move(callback));
|
393
|
-
return;
|
394
|
-
}
|
395
|
-
callback({});
|
396
|
-
});
|
397
|
-
} catch (const client_error& e) {
|
398
|
-
handle_rollback_insert_error(e, ctx, item, delay, std::move(callback));
|
399
|
-
return;
|
371
|
+
return callback({});
|
372
|
+
};
|
373
|
+
|
374
|
+
auto ec = ctx->error_if_expired_and_not_in_overtime(STAGE_DELETE_INSERTED, item.doc().id().key());
|
375
|
+
if (ec) {
|
376
|
+
return handler(client_error(*ec, "expired in rollback and not in overtime mode"));
|
400
377
|
}
|
378
|
+
|
379
|
+
return ctx->hooks_.before_rollback_delete_inserted(
|
380
|
+
ctx, item.doc().id().key(), [handler = std::move(handler), ctx, &item, delay](std::optional<error_class> ec) mutable {
|
381
|
+
if (ec) {
|
382
|
+
return handler(client_error(*ec, "before_rollback_delete_insert hook threw error"));
|
383
|
+
}
|
384
|
+
core::operations::mutate_in_request req{ item.doc().id() };
|
385
|
+
req.specs =
|
386
|
+
couchbase::mutate_in_specs{
|
387
|
+
couchbase::mutate_in_specs::remove(TRANSACTION_INTERFACE_PREFIX_ONLY).xattr(),
|
388
|
+
}
|
389
|
+
.specs();
|
390
|
+
req.access_deleted = true;
|
391
|
+
req.cas = item.doc().cas();
|
392
|
+
wrap_durable_request(req, ctx->overall().config());
|
393
|
+
return ctx->cluster_ref().execute(
|
394
|
+
req, [handler = std::move(handler), ctx, &item, delay](const core::operations::mutate_in_response& resp) mutable {
|
395
|
+
CB_ATTEMPT_CTX_LOG_TRACE(ctx, "mutate_in for {} with cas {}", item.doc().id(), item.doc().cas().value());
|
396
|
+
|
397
|
+
auto res = result::create_from_subdoc_response(resp);
|
398
|
+
return validate_rollback_insert_result(ctx, res, item, std::move(handler));
|
399
|
+
});
|
400
|
+
});
|
401
401
|
}));
|
402
402
|
}
|
403
403
|
|
404
404
|
void
|
405
405
|
staged_mutation_queue::rollback_remove_or_replace(attempt_context_impl* ctx,
|
406
406
|
const staged_mutation& item,
|
407
|
-
async_exp_delay delay,
|
407
|
+
async_exp_delay& delay,
|
408
408
|
utils::movable_function<void(std::exception_ptr)> callback)
|
409
409
|
{
|
410
410
|
CB_ATTEMPT_CTX_LOG_TRACE(ctx, "rolling back staged remove/replace for {} with cas {}", item.doc().id(), item.doc().cas().value());
|
411
411
|
|
412
412
|
asio::post(asio::bind_executor(ctx->cluster_ref().io_context(), [this, callback = std::move(callback), ctx, &item, delay]() mutable {
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
throw client_error(*ec, "expired in rollback_remove_or_replace and not in expiry overtime");
|
413
|
+
auto handler = [this, callback = std::move(callback), ctx, &item, delay](const std::optional<client_error>& e) mutable {
|
414
|
+
if (e) {
|
415
|
+
return handle_rollback_remove_or_replace_error(e.value(), ctx, item, delay, std::move(callback));
|
417
416
|
}
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
req.specs =
|
424
|
-
couchbase::mutate_in_specs{
|
425
|
-
couchbase::mutate_in_specs::remove(TRANSACTION_INTERFACE_PREFIX_ONLY).xattr(),
|
426
|
-
}
|
427
|
-
.specs();
|
428
|
-
req.cas = item.doc().cas();
|
429
|
-
wrap_durable_request(req, ctx->overall().config());
|
430
|
-
return ctx->cluster_ref().execute(
|
431
|
-
req, [this, callback = std::move(callback), ctx, &item, delay](const core::operations::mutate_in_response& resp) mutable {
|
432
|
-
auto res = result::create_from_subdoc_response(resp);
|
433
|
-
try {
|
434
|
-
validate_rollback_remove_or_replace_result(ctx, res, item);
|
435
|
-
} catch (const client_error& e) {
|
436
|
-
handle_rollback_remove_or_replace_error(e, ctx, item, delay, std::move(callback));
|
437
|
-
return;
|
438
|
-
}
|
439
|
-
callback({});
|
440
|
-
});
|
441
|
-
} catch (const client_error& e) {
|
442
|
-
handle_rollback_remove_or_replace_error(e, ctx, item, delay, std::move(callback));
|
443
|
-
return;
|
417
|
+
return callback({});
|
418
|
+
};
|
419
|
+
auto ec = ctx->error_if_expired_and_not_in_overtime(STAGE_ROLLBACK_DOC, item.doc().id().key());
|
420
|
+
if (ec) {
|
421
|
+
return handler(client_error(*ec, "expired in rollback_remove_or_replace and not in expiry overtime"));
|
444
422
|
}
|
423
|
+
ctx->hooks_.before_doc_rolled_back(
|
424
|
+
ctx, item.doc().id().key(), [handler = std::move(handler), ctx, &item, delay](std::optional<error_class> ec) mutable {
|
425
|
+
if (ec) {
|
426
|
+
return handler(client_error(*ec, "before_doc_rolled_back hook threw error"));
|
427
|
+
}
|
428
|
+
core::operations::mutate_in_request req{ item.doc().id() };
|
429
|
+
req.specs =
|
430
|
+
couchbase::mutate_in_specs{
|
431
|
+
couchbase::mutate_in_specs::remove(TRANSACTION_INTERFACE_PREFIX_ONLY).xattr(),
|
432
|
+
}
|
433
|
+
.specs();
|
434
|
+
req.cas = item.doc().cas();
|
435
|
+
wrap_durable_request(req, ctx->overall().config());
|
436
|
+
return ctx->cluster_ref().execute(
|
437
|
+
req, [handler = std::move(handler), ctx, &item, delay](const core::operations::mutate_in_response& resp) mutable {
|
438
|
+
auto res = result::create_from_subdoc_response(resp);
|
439
|
+
return validate_rollback_remove_or_replace_result(ctx, res, item, std::move(handler));
|
440
|
+
});
|
441
|
+
});
|
445
442
|
}));
|
446
443
|
}
|
447
444
|
|
448
445
|
void
|
449
446
|
staged_mutation_queue::commit_doc(attempt_context_impl* ctx,
|
450
447
|
staged_mutation& item,
|
451
|
-
async_constant_delay delay,
|
448
|
+
async_constant_delay& delay,
|
452
449
|
utils::movable_function<void(std::exception_ptr)> callback,
|
453
450
|
bool ambiguity_resolution_mode,
|
454
451
|
bool cas_zero_mode)
|
@@ -459,158 +456,204 @@ staged_mutation_queue::commit_doc(attempt_context_impl* ctx,
|
|
459
456
|
asio::post(asio::bind_executor(
|
460
457
|
ctx->cluster_ref().io_context(),
|
461
458
|
[this, callback = std::move(callback), ctx, &item, delay, cas_zero_mode, ambiguity_resolution_mode]() mutable {
|
462
|
-
|
463
|
-
ctx->check_expiry_during_commit_or_rollback(STAGE_COMMIT_DOC, std::optional<const std::string>(item.doc().id().key()));
|
464
|
-
auto ec = ctx->hooks_.before_doc_committed(ctx, item.doc().id().key());
|
465
|
-
if (ec) {
|
466
|
-
throw client_error(*ec, "before_doc_committed hook threw error");
|
467
|
-
}
|
459
|
+
ctx->check_expiry_during_commit_or_rollback(STAGE_COMMIT_DOC, std::optional<const std::string>(item.doc().id().key()));
|
468
460
|
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
core::operations::insert_request req{ item.doc().id(), item.content() };
|
475
|
-
req.flags = couchbase::codec::codec_flags::json_common_flags;
|
476
|
-
wrap_durable_request(req, ctx->overall().config());
|
477
|
-
return ctx->cluster_ref().execute(
|
478
|
-
req,
|
479
|
-
[this, callback = std::move(callback), ctx, &item, delay, ambiguity_resolution_mode, cas_zero_mode](
|
480
|
-
const core::operations::insert_response& resp) mutable {
|
481
|
-
auto res = result::create_from_mutation_response(resp);
|
482
|
-
try {
|
483
|
-
validate_commit_doc_result(ctx, res, item);
|
484
|
-
} catch (const client_error& e) {
|
485
|
-
handle_commit_doc_error(e, ctx, item, delay, ambiguity_resolution_mode, cas_zero_mode, std::move(callback));
|
486
|
-
return;
|
487
|
-
}
|
488
|
-
// Commit successful
|
489
|
-
callback({});
|
490
|
-
});
|
491
|
-
} else {
|
492
|
-
core::operations::mutate_in_request req{ item.doc().id() };
|
493
|
-
req.specs =
|
494
|
-
couchbase::mutate_in_specs{
|
495
|
-
couchbase::mutate_in_specs::remove(TRANSACTION_INTERFACE_PREFIX_ONLY).xattr(),
|
496
|
-
// subdoc::opcode::set_doc used in replace w/ empty path
|
497
|
-
couchbase::mutate_in_specs::replace_raw("", item.content()),
|
498
|
-
}
|
499
|
-
.specs();
|
500
|
-
req.store_semantics = couchbase::store_semantics::replace;
|
501
|
-
req.cas = couchbase::cas(cas_zero_mode ? 0 : item.doc().cas().value());
|
502
|
-
wrap_durable_request(req, ctx->overall().config());
|
503
|
-
return ctx->cluster_ref().execute(
|
504
|
-
req,
|
505
|
-
[this, callback = std::move(callback), ctx, &item, delay, ambiguity_resolution_mode, cas_zero_mode](
|
506
|
-
const core::operations::mutate_in_response resp) mutable {
|
507
|
-
auto res = result::create_from_subdoc_response(resp);
|
508
|
-
try {
|
509
|
-
validate_commit_doc_result(ctx, res, item);
|
510
|
-
} catch (const client_error& e) {
|
511
|
-
handle_commit_doc_error(e, ctx, item, delay, ambiguity_resolution_mode, cas_zero_mode, std::move(callback));
|
512
|
-
return;
|
513
|
-
}
|
514
|
-
// Commit successful
|
515
|
-
callback({});
|
516
|
-
});
|
461
|
+
auto handler = [this, callback = std::move(callback), ctx, &item, delay](
|
462
|
+
const std::optional<client_error>& e, bool ambiguity_resolution_mode, bool cas_zero_mode) mutable {
|
463
|
+
if (e) {
|
464
|
+
return handle_commit_doc_error(
|
465
|
+
e.value(), ctx, item, delay, ambiguity_resolution_mode, cas_zero_mode, std::move(callback));
|
517
466
|
}
|
518
|
-
|
519
|
-
|
520
|
-
|
467
|
+
callback({});
|
468
|
+
};
|
469
|
+
|
470
|
+
ctx->hooks_.before_doc_committed(
|
471
|
+
ctx,
|
472
|
+
item.doc().id().key(),
|
473
|
+
[handler = std::move(handler), ctx, &item, delay, ambiguity_resolution_mode, cas_zero_mode](
|
474
|
+
std::optional<error_class> ec) mutable {
|
475
|
+
if (ec) {
|
476
|
+
return handler(client_error(*ec, "before_doc_committed hook threw error"), ambiguity_resolution_mode, cas_zero_mode);
|
477
|
+
}
|
478
|
+
// move staged content into doc
|
479
|
+
CB_ATTEMPT_CTX_LOG_TRACE(
|
480
|
+
ctx, "commit doc id {}, content {}, cas {}", item.doc().id(), to_string(item.content()), item.doc().cas().value());
|
481
|
+
|
482
|
+
if (item.type() == staged_mutation_type::INSERT && !cas_zero_mode) {
|
483
|
+
core::operations::insert_request req{ item.doc().id(), item.content() };
|
484
|
+
req.flags = couchbase::codec::codec_flags::json_common_flags;
|
485
|
+
wrap_durable_request(req, ctx->overall().config());
|
486
|
+
return ctx->cluster_ref().execute(
|
487
|
+
req,
|
488
|
+
[handler = std::move(handler), ctx, &item, delay, ambiguity_resolution_mode, cas_zero_mode](
|
489
|
+
const core::operations::insert_response& resp) mutable {
|
490
|
+
auto res = result::create_from_mutation_response(resp);
|
491
|
+
return validate_commit_doc_result(
|
492
|
+
ctx, res, item, [ambiguity_resolution_mode, cas_zero_mode, handler = std::move(handler)](auto e) mutable {
|
493
|
+
if (e) {
|
494
|
+
return handler(e, ambiguity_resolution_mode, cas_zero_mode);
|
495
|
+
}
|
496
|
+
// Commit successful
|
497
|
+
return handler({}, {}, {});
|
498
|
+
});
|
499
|
+
});
|
500
|
+
} else {
|
501
|
+
core::operations::mutate_in_request req{ item.doc().id() };
|
502
|
+
req.specs =
|
503
|
+
couchbase::mutate_in_specs{
|
504
|
+
couchbase::mutate_in_specs::remove(TRANSACTION_INTERFACE_PREFIX_ONLY).xattr(),
|
505
|
+
// subdoc::opcode::set_doc used in replace w/ empty path
|
506
|
+
couchbase::mutate_in_specs::replace_raw("", item.content()),
|
507
|
+
}
|
508
|
+
.specs();
|
509
|
+
req.store_semantics = couchbase::store_semantics::replace;
|
510
|
+
req.cas = couchbase::cas(cas_zero_mode ? 0 : item.doc().cas().value());
|
511
|
+
wrap_durable_request(req, ctx->overall().config());
|
512
|
+
return ctx->cluster_ref().execute(
|
513
|
+
req,
|
514
|
+
[handler = std::move(handler), ctx, &item, delay, ambiguity_resolution_mode, cas_zero_mode](
|
515
|
+
const core::operations::mutate_in_response resp) mutable {
|
516
|
+
auto res = result::create_from_subdoc_response(resp);
|
517
|
+
return validate_commit_doc_result(
|
518
|
+
ctx, res, item, [ambiguity_resolution_mode, cas_zero_mode, handler = std::move(handler)](auto e) mutable {
|
519
|
+
if (e) {
|
520
|
+
return handler(e, ambiguity_resolution_mode, cas_zero_mode);
|
521
|
+
}
|
522
|
+
// Commit successful
|
523
|
+
return handler({}, {}, {});
|
524
|
+
});
|
525
|
+
});
|
526
|
+
}
|
527
|
+
});
|
521
528
|
}));
|
522
529
|
}
|
523
530
|
|
524
531
|
void
|
525
532
|
staged_mutation_queue::remove_doc(attempt_context_impl* ctx,
|
526
533
|
const staged_mutation& item,
|
527
|
-
async_constant_delay delay,
|
534
|
+
async_constant_delay& delay,
|
528
535
|
utils::movable_function<void(std::exception_ptr)> callback)
|
529
536
|
{
|
530
537
|
CB_ATTEMPT_CTX_LOG_TRACE(ctx, "remove doc {}", item.doc().id());
|
531
538
|
|
532
539
|
asio::post(asio::bind_executor(ctx->cluster_ref().io_context(), [this, callback = std::move(callback), ctx, &item, delay]() mutable {
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
if (ec) {
|
537
|
-
throw client_error(*ec, "before_doc_removed hook threw error");
|
540
|
+
auto handler = [this, ctx, &item, delay, callback = std::move(callback)](const std::optional<client_error>& e) mutable {
|
541
|
+
if (e) {
|
542
|
+
return handle_remove_doc_error(e.value(), ctx, item, delay, std::move(callback));
|
538
543
|
}
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
544
|
+
return callback({});
|
545
|
+
};
|
546
|
+
|
547
|
+
ctx->check_expiry_during_commit_or_rollback(STAGE_REMOVE_DOC, std::optional<const std::string>(item.doc().id().key()));
|
548
|
+
return ctx->hooks_.before_doc_removed(
|
549
|
+
ctx, item.doc().id().key(), [ctx, &item, delay, handler = std::move(handler)](auto ec) mutable {
|
550
|
+
if (ec) {
|
551
|
+
return handler(client_error(*ec, "before_doc_removed hook threw error"));
|
552
|
+
}
|
553
|
+
core::operations::remove_request req{ item.doc().id() };
|
554
|
+
wrap_durable_request(req, ctx->overall().config());
|
555
|
+
return ctx->cluster_ref().execute(
|
556
|
+
req, [handler = std::move(handler), ctx, &item, delay](core::operations::remove_response resp) mutable {
|
557
|
+
auto res = result::create_from_mutation_response(resp);
|
558
|
+
return validate_remove_doc_result(ctx, res, item, std::move(handler));
|
559
|
+
});
|
560
|
+
});
|
555
561
|
}));
|
556
562
|
}
|
557
563
|
|
558
564
|
void
|
559
|
-
staged_mutation_queue::validate_commit_doc_result(attempt_context_impl* ctx,
|
565
|
+
staged_mutation_queue::validate_commit_doc_result(attempt_context_impl* ctx,
|
566
|
+
result& res,
|
567
|
+
staged_mutation& item,
|
568
|
+
client_error_handler&& handler)
|
560
569
|
{
|
561
|
-
|
570
|
+
try {
|
571
|
+
validate_operation_result(res);
|
572
|
+
} catch (const client_error& e) {
|
573
|
+
return handler(e);
|
574
|
+
}
|
562
575
|
CB_ATTEMPT_CTX_LOG_TRACE(ctx, "commit doc result {}", res);
|
563
576
|
// TODO: mutation tokens
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
577
|
+
ctx->hooks_.after_doc_committed_before_saving_cas(
|
578
|
+
ctx, item.doc().id().key(), [ctx, res, item, handler = std::move(handler)](auto ec) mutable {
|
579
|
+
if (ec) {
|
580
|
+
return handler(client_error(*ec, "after_doc_committed_before_saving_cas threw error"));
|
581
|
+
}
|
582
|
+
item.doc().cas(res.cas);
|
583
|
+
return ctx->hooks_.after_doc_committed(ctx, item.doc().id().key(), [res, item, handler = std::move(handler)](auto ec) mutable {
|
584
|
+
if (ec) {
|
585
|
+
return handler(client_error(*ec, "after_doc_committed threw error"));
|
586
|
+
}
|
587
|
+
return handler({});
|
588
|
+
});
|
589
|
+
});
|
573
590
|
}
|
574
591
|
|
575
592
|
void
|
576
|
-
staged_mutation_queue::validate_remove_doc_result(attempt_context_impl* ctx,
|
593
|
+
staged_mutation_queue::validate_remove_doc_result(attempt_context_impl* ctx,
|
594
|
+
result& res,
|
595
|
+
const staged_mutation& item,
|
596
|
+
client_error_handler&& handler)
|
577
597
|
{
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
if (ec) {
|
583
|
-
throw client_error(*ec, "after_doc_removed_pre_retry threw error");
|
598
|
+
try {
|
599
|
+
validate_operation_result(res);
|
600
|
+
} catch (const client_error& e) {
|
601
|
+
return handler(e);
|
584
602
|
}
|
603
|
+
CB_ATTEMPT_CTX_LOG_TRACE(ctx, "remove doc result {}", res);
|
604
|
+
return ctx->hooks_.after_doc_removed_pre_retry(ctx, item.doc().id().key(), [handler = std::move(handler)](auto ec) {
|
605
|
+
if (ec) {
|
606
|
+
return handler(client_error(*ec, "after_doc_removed_pre_retry threw error"));
|
607
|
+
}
|
608
|
+
return handler({});
|
609
|
+
});
|
585
610
|
}
|
586
611
|
|
587
612
|
void
|
588
|
-
staged_mutation_queue::validate_rollback_insert_result(attempt_context_impl* ctx,
|
613
|
+
staged_mutation_queue::validate_rollback_insert_result(attempt_context_impl* ctx,
|
614
|
+
result& res,
|
615
|
+
const staged_mutation& item,
|
616
|
+
client_error_handler&& handler)
|
589
617
|
{
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
throw client_error(*ec, "after_rollback_delete_insert hook threw error");
|
618
|
+
try {
|
619
|
+
validate_operation_result(res);
|
620
|
+
} catch (const client_error& e) {
|
621
|
+
return handler(e);
|
595
622
|
}
|
623
|
+
CB_ATTEMPT_CTX_LOG_TRACE(ctx, "rollback insert result {}", res);
|
624
|
+
return ctx->hooks_.after_rollback_delete_inserted(ctx, item.doc().id().key(), [handler = std::move(handler)](auto ec) {
|
625
|
+
if (ec) {
|
626
|
+
return handler(client_error(*ec, "after_rollback_delete_insert hook threw error"));
|
627
|
+
}
|
628
|
+
return handler({});
|
629
|
+
});
|
596
630
|
}
|
597
631
|
|
598
632
|
void
|
599
|
-
staged_mutation_queue::validate_rollback_remove_or_replace_result(attempt_context_impl* ctx,
|
633
|
+
staged_mutation_queue::validate_rollback_remove_or_replace_result(attempt_context_impl* ctx,
|
634
|
+
result& res,
|
635
|
+
const staged_mutation& item,
|
636
|
+
client_error_handler&& handler)
|
600
637
|
{
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
throw client_error(*ec, "after_rollback_replace_or_remove hook threw error");
|
638
|
+
try {
|
639
|
+
validate_operation_result(res);
|
640
|
+
} catch (const client_error& e) {
|
641
|
+
return handler(e);
|
606
642
|
}
|
643
|
+
CB_ATTEMPT_CTX_LOG_TRACE(ctx, "rollback remove or replace result {}", res);
|
644
|
+
return ctx->hooks_.after_rollback_replace_or_remove(ctx, item.doc().id().key(), [handler = std::move(handler)](auto ec) {
|
645
|
+
if (ec) {
|
646
|
+
return handler(client_error(*ec, "after_rollback_replace_or_remove hook threw error"));
|
647
|
+
}
|
648
|
+
return handler({});
|
649
|
+
});
|
607
650
|
}
|
608
651
|
|
609
652
|
void
|
610
653
|
staged_mutation_queue::handle_commit_doc_error(const client_error& e,
|
611
654
|
attempt_context_impl* ctx,
|
612
655
|
staged_mutation& item,
|
613
|
-
async_constant_delay delay,
|
656
|
+
async_constant_delay& delay,
|
614
657
|
bool ambiguity_resolution_mode,
|
615
658
|
bool cas_zero_mode,
|
616
659
|
utils::movable_function<void(std::exception_ptr)> callback)
|
@@ -656,7 +699,7 @@ void
|
|
656
699
|
staged_mutation_queue::handle_remove_doc_error(const client_error& e,
|
657
700
|
attempt_context_impl* ctx,
|
658
701
|
const staged_mutation& item,
|
659
|
-
async_constant_delay delay,
|
702
|
+
async_constant_delay& delay,
|
660
703
|
utils::movable_function<void(std::exception_ptr)> callback)
|
661
704
|
{
|
662
705
|
auto ec = e.ec();
|
@@ -690,7 +733,7 @@ void
|
|
690
733
|
staged_mutation_queue::handle_rollback_insert_error(const client_error& e,
|
691
734
|
attempt_context_impl* ctx,
|
692
735
|
const staged_mutation& item,
|
693
|
-
async_exp_delay delay,
|
736
|
+
async_exp_delay& delay,
|
694
737
|
utils::movable_function<void(std::exception_ptr)> callback)
|
695
738
|
{
|
696
739
|
auto ec = e.ec();
|
@@ -736,7 +779,7 @@ void
|
|
736
779
|
staged_mutation_queue::handle_rollback_remove_or_replace_error(const client_error& e,
|
737
780
|
attempt_context_impl* ctx,
|
738
781
|
const staged_mutation& item,
|
739
|
-
async_exp_delay delay,
|
782
|
+
async_exp_delay& delay,
|
740
783
|
utils::movable_function<void(std::exception_ptr)> callback)
|
741
784
|
{
|
742
785
|
auto ec = e.ec();
|
@@ -129,51 +129,62 @@ class staged_mutation_queue
|
|
129
129
|
std::mutex mutex_;
|
130
130
|
std::vector<staged_mutation> queue_;
|
131
131
|
|
132
|
-
|
133
|
-
|
134
|
-
static void
|
135
|
-
|
132
|
+
using client_error_handler = utils::movable_function<void(const std::optional<client_error>&)>;
|
133
|
+
|
134
|
+
static void validate_rollback_remove_or_replace_result(attempt_context_impl* ctx,
|
135
|
+
result& res,
|
136
|
+
const staged_mutation& item,
|
137
|
+
client_error_handler&& handler);
|
138
|
+
static void validate_rollback_insert_result(attempt_context_impl* ctx,
|
139
|
+
result& res,
|
140
|
+
const staged_mutation& item,
|
141
|
+
client_error_handler&& handler);
|
142
|
+
static void validate_commit_doc_result(attempt_context_impl* ctx, result& res, staged_mutation& item, client_error_handler&& handler);
|
143
|
+
static void validate_remove_doc_result(attempt_context_impl* ctx,
|
144
|
+
result& res,
|
145
|
+
const staged_mutation& item,
|
146
|
+
client_error_handler&& handler);
|
136
147
|
|
137
148
|
void handle_commit_doc_error(const client_error& e,
|
138
149
|
attempt_context_impl* ctx,
|
139
150
|
staged_mutation& item,
|
140
|
-
async_constant_delay delay,
|
151
|
+
async_constant_delay& delay,
|
141
152
|
bool ambiguity_resolution_mode,
|
142
153
|
bool cas_zero_mode,
|
143
154
|
utils::movable_function<void(std::exception_ptr)> callback);
|
144
155
|
void handle_remove_doc_error(const client_error& e,
|
145
156
|
attempt_context_impl* ctx,
|
146
157
|
const staged_mutation& item,
|
147
|
-
async_constant_delay delay,
|
158
|
+
async_constant_delay& delay,
|
148
159
|
utils::movable_function<void(std::exception_ptr)> callback);
|
149
160
|
void handle_rollback_insert_error(const client_error& e,
|
150
161
|
attempt_context_impl* ctx,
|
151
162
|
const staged_mutation& item,
|
152
|
-
async_exp_delay delay,
|
163
|
+
async_exp_delay& delay,
|
153
164
|
utils::movable_function<void(std::exception_ptr)> callback);
|
154
165
|
void handle_rollback_remove_or_replace_error(const client_error& e,
|
155
166
|
attempt_context_impl* ctx,
|
156
167
|
const staged_mutation& item,
|
157
|
-
async_exp_delay delay,
|
168
|
+
async_exp_delay& delay,
|
158
169
|
utils::movable_function<void(std::exception_ptr)> callback);
|
159
170
|
|
160
171
|
void commit_doc(attempt_context_impl* ctx,
|
161
172
|
staged_mutation& item,
|
162
|
-
async_constant_delay delay,
|
173
|
+
async_constant_delay& delay,
|
163
174
|
utils::movable_function<void(std::exception_ptr)> callback,
|
164
175
|
bool ambiguity_resolution_mode = false,
|
165
176
|
bool cas_zero_mode = false);
|
166
177
|
void remove_doc(attempt_context_impl* ctx,
|
167
178
|
const staged_mutation& item,
|
168
|
-
async_constant_delay delay,
|
179
|
+
async_constant_delay& delay,
|
169
180
|
utils::movable_function<void(std::exception_ptr)> callback);
|
170
181
|
void rollback_insert(attempt_context_impl* ctx,
|
171
182
|
const staged_mutation& item,
|
172
|
-
async_exp_delay delay,
|
183
|
+
async_exp_delay& delay,
|
173
184
|
utils::movable_function<void(std::exception_ptr)> callback);
|
174
185
|
void rollback_remove_or_replace(attempt_context_impl* ctx,
|
175
186
|
const staged_mutation& item,
|
176
|
-
async_exp_delay delay,
|
187
|
+
async_exp_delay& delay,
|
177
188
|
utils::movable_function<void(std::exception_ptr)> callback);
|
178
189
|
|
179
190
|
public:
|