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
@@ -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:
|