couchbase 4.2.1 → 4.2.2
Sign up to get free protection for your applications and to get access to all the features.
- package/CMakeLists.txt +1 -0
- package/deps/couchbase-cxx-client/.gitmodules +3 -0
- package/deps/couchbase-cxx-client/.idea/misc.xml +1 -0
- package/deps/couchbase-cxx-client/.idea/vcs.xml +1 -0
- package/deps/couchbase-cxx-client/CMakeLists.txt +11 -1
- package/deps/couchbase-cxx-client/README.md +3 -3
- package/deps/couchbase-cxx-client/cmake/CompilerWarnings.cmake +4 -1
- package/deps/couchbase-cxx-client/cmake/VersionInfo.cmake +13 -1
- package/deps/couchbase-cxx-client/cmake/build_version.hxx.in +1 -0
- package/deps/couchbase-cxx-client/core/cluster.hxx +15 -5
- package/deps/couchbase-cxx-client/core/impl/build_deferred_query_indexes.cxx +17 -6
- package/deps/couchbase-cxx-client/core/impl/cluster.cxx +1 -1
- package/deps/couchbase-cxx-client/core/impl/collection_query_index_manager.cxx +93 -0
- package/deps/couchbase-cxx-client/core/impl/configuration_profiles_registry.cxx +11 -0
- package/deps/couchbase-cxx-client/core/impl/create_query_index.cxx +119 -0
- package/deps/couchbase-cxx-client/core/impl/drop_query_index.cxx +108 -0
- package/deps/couchbase-cxx-client/core/impl/get.cxx +1 -1
- package/deps/couchbase-cxx-client/core/impl/get_all_query_indexes.cxx +76 -0
- package/deps/couchbase-cxx-client/core/impl/query.cxx +5 -7
- package/deps/couchbase-cxx-client/core/impl/watch_query_indexes.cxx +168 -0
- package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +15 -1
- package/deps/couchbase-cxx-client/core/logger/configuration.hxx +3 -0
- package/deps/couchbase-cxx-client/core/logger/level.hxx +21 -0
- package/deps/couchbase-cxx-client/core/logger/logger.hxx +4 -6
- package/deps/couchbase-cxx-client/core/meta/CMakeLists.txt +4 -2
- package/deps/couchbase-cxx-client/core/meta/features.hxx +31 -0
- package/deps/couchbase-cxx-client/core/meta/version.cxx +67 -5
- package/deps/couchbase-cxx-client/core/meta/version.hxx +12 -1
- package/deps/couchbase-cxx-client/core/metrics/CMakeLists.txt +4 -1
- package/deps/couchbase-cxx-client/core/metrics/logging_meter.cxx +46 -5
- package/deps/couchbase-cxx-client/core/metrics/logging_meter.hxx +10 -26
- package/deps/couchbase-cxx-client/core/operations/document_get_projected.cxx +3 -2
- package/deps/couchbase-cxx-client/core/operations/document_query.cxx +10 -12
- package/deps/couchbase-cxx-client/core/operations/document_query.hxx +1 -3
- package/deps/couchbase-cxx-client/core/operations/management/query_index_build.cxx +8 -14
- package/deps/couchbase-cxx-client/core/operations/management/query_index_build.hxx +2 -1
- package/deps/couchbase-cxx-client/core/operations/management/query_index_build_deferred.hxx +15 -8
- package/deps/couchbase-cxx-client/core/operations/management/query_index_create.cxx +7 -14
- package/deps/couchbase-cxx-client/core/operations/management/query_index_create.hxx +2 -0
- package/deps/couchbase-cxx-client/core/operations/management/query_index_drop.cxx +11 -16
- package/deps/couchbase-cxx-client/core/operations/management/query_index_drop.hxx +2 -0
- package/deps/couchbase-cxx-client/core/operations/management/query_index_get_all.cxx +8 -12
- package/deps/couchbase-cxx-client/core/operations/management/query_index_get_all.hxx +4 -3
- package/deps/couchbase-cxx-client/core/operations/management/query_index_get_all_deferred.cxx +21 -12
- package/deps/couchbase-cxx-client/core/operations/management/query_index_get_all_deferred.hxx +3 -2
- package/deps/couchbase-cxx-client/core/origin.hxx +1 -1
- package/deps/couchbase-cxx-client/core/platform/uuid.cc +1 -2
- package/deps/couchbase-cxx-client/core/protocol/cmd_hello.hxx +5 -1
- package/deps/couchbase-cxx-client/core/query_context.hxx +79 -0
- package/deps/couchbase-cxx-client/core/tracing/CMakeLists.txt +3 -1
- package/deps/couchbase-cxx-client/core/tracing/threshold_logging_tracer.cxx +19 -4
- package/deps/couchbase-cxx-client/core/tracing/threshold_logging_tracer.hxx +2 -2
- package/deps/couchbase-cxx-client/core/transactions/async_attempt_context.hxx +10 -4
- package/deps/couchbase-cxx-client/core/transactions/atr_cleanup_entry.cxx +52 -63
- package/deps/couchbase-cxx-client/core/transactions/attempt_context.hxx +8 -3
- package/deps/couchbase-cxx-client/core/transactions/attempt_context_impl.cxx +163 -126
- package/deps/couchbase-cxx-client/core/transactions/attempt_context_impl.hxx +24 -37
- package/deps/couchbase-cxx-client/core/transactions/forward_compat.hxx +4 -4
- package/deps/couchbase-cxx-client/core/transactions/internal/atr_cleanup_entry.hxx +51 -13
- package/deps/couchbase-cxx-client/core/transactions/internal/client_record.hxx +26 -1
- package/deps/couchbase-cxx-client/core/transactions/internal/doc_record.hxx +21 -0
- package/deps/couchbase-cxx-client/core/transactions/internal/logging.hxx +40 -18
- package/deps/couchbase-cxx-client/core/transactions/internal/transaction_context.hxx +5 -0
- package/deps/couchbase-cxx-client/core/transactions/result.hxx +26 -0
- package/deps/couchbase-cxx-client/core/transactions/staged_mutation.cxx +48 -47
- package/deps/couchbase-cxx-client/core/transactions/staged_mutation.hxx +6 -6
- package/deps/couchbase-cxx-client/core/transactions/transaction_context.cxx +33 -19
- package/deps/couchbase-cxx-client/core/transactions/transaction_get_result.hxx +18 -2
- package/deps/couchbase-cxx-client/core/transactions/transaction_links.hxx +25 -2
- package/deps/couchbase-cxx-client/core/transactions/transactions.cxx +4 -4
- package/deps/couchbase-cxx-client/core/transactions/transactions_cleanup.cxx +49 -56
- package/deps/couchbase-cxx-client/core/transactions/waitable_op_list.hxx +7 -7
- package/deps/couchbase-cxx-client/core/transactions.hxx +0 -12
- package/deps/couchbase-cxx-client/core/utils/binary.hxx +1 -1
- package/deps/couchbase-cxx-client/core/utils/keyspace.hxx +55 -0
- package/deps/couchbase-cxx-client/couchbase/build_query_index_options.hxx +12 -45
- package/deps/couchbase-cxx-client/couchbase/cluster.hxx +1 -1
- package/deps/couchbase-cxx-client/couchbase/cluster_options.hxx +6 -7
- package/deps/couchbase-cxx-client/couchbase/collection.hxx +8 -0
- package/deps/couchbase-cxx-client/couchbase/collection_query_index_manager.hxx +218 -0
- package/deps/couchbase-cxx-client/couchbase/configuration_profiles_registry.hxx +3 -0
- package/deps/couchbase-cxx-client/couchbase/create_primary_query_index_options.hxx +166 -0
- package/deps/couchbase-cxx-client/couchbase/create_query_index_options.hxx +172 -0
- package/deps/couchbase-cxx-client/couchbase/drop_primary_query_index_options.hxx +129 -0
- package/deps/couchbase-cxx-client/couchbase/drop_query_index_options.hxx +116 -0
- package/deps/couchbase-cxx-client/couchbase/fmt/cas.hxx +1 -1
- package/deps/couchbase-cxx-client/couchbase/fmt/query_scan_consistency.hxx +46 -0
- package/deps/couchbase-cxx-client/couchbase/fmt/query_status.hxx +70 -0
- package/deps/couchbase-cxx-client/couchbase/fmt/tls_verify_mode.hxx +46 -0
- package/deps/couchbase-cxx-client/couchbase/get_all_query_indexes_options.hxx +100 -0
- package/deps/couchbase-cxx-client/{core → couchbase}/management/query_index.hxx +2 -2
- package/deps/couchbase-cxx-client/couchbase/metrics/meter.hxx +16 -0
- package/deps/couchbase-cxx-client/couchbase/query_index_manager.hxx +178 -6
- package/deps/couchbase-cxx-client/couchbase/query_options.hxx +1 -18
- package/deps/couchbase-cxx-client/couchbase/scope.hxx +5 -2
- package/deps/couchbase-cxx-client/couchbase/tracing/request_tracer.hxx +16 -0
- package/deps/couchbase-cxx-client/couchbase/transactions/async_attempt_context.hxx +11 -4
- package/deps/couchbase-cxx-client/couchbase/transactions/attempt_context.hxx +5 -3
- package/deps/couchbase-cxx-client/couchbase/transactions/transaction_keyspace.hxx +16 -0
- package/deps/couchbase-cxx-client/couchbase/transactions/transaction_query_options.hxx +0 -6
- package/deps/couchbase-cxx-client/couchbase/watch_query_indexes_options.hxx +115 -0
- package/deps/couchbase-cxx-client/examples/minimal.cxx +3 -1
- package/deps/couchbase-cxx-client/test/test_integration_crud.cxx +72 -0
- package/deps/couchbase-cxx-client/test/test_integration_management.cxx +727 -310
- package/deps/couchbase-cxx-client/test/test_integration_query.cxx +4 -8
- package/deps/couchbase-cxx-client/test/test_integration_transcoders.cxx +14 -0
- package/deps/couchbase-cxx-client/test/test_transaction_transaction_public_blocking_api.cxx +34 -19
- package/deps/couchbase-cxx-client/test/test_unit_transaction_logging.cxx +66 -22
- package/deps/couchbase-cxx-client/test/test_unit_utils.cxx +51 -0
- package/deps/couchbase-cxx-client/test/tools/tool_kv_loader.cxx +2 -2
- package/deps/couchbase-cxx-client/test/utils/integration_test_guard.cxx +2 -0
- package/deps/couchbase-cxx-client/test/utils/wait_until.cxx +4 -4
- package/deps/couchbase-cxx-client/third_party/docopt/.travis.yml +103 -0
- package/deps/couchbase-cxx-client/third_party/docopt/CMakeLists.txt +129 -0
- package/deps/couchbase-cxx-client/third_party/docopt/LICENSE-Boost-1.0 +23 -0
- package/deps/couchbase-cxx-client/third_party/docopt/LICENSE-MIT +23 -0
- package/deps/couchbase-cxx-client/third_party/docopt/README.rst +479 -0
- package/deps/couchbase-cxx-client/third_party/docopt/docopt-config.cmake +1 -0
- package/deps/couchbase-cxx-client/third_party/docopt/docopt.cpp +687 -0
- package/deps/couchbase-cxx-client/third_party/docopt/docopt.h +98 -0
- package/deps/couchbase-cxx-client/third_party/docopt/docopt.pc.in +9 -0
- package/deps/couchbase-cxx-client/third_party/docopt/docopt_private.h +676 -0
- package/deps/couchbase-cxx-client/third_party/docopt/docopt_util.h +122 -0
- package/deps/couchbase-cxx-client/third_party/docopt/docopt_value.h +341 -0
- package/deps/couchbase-cxx-client/third_party/docopt/examples/naval_fate.cpp +36 -0
- package/deps/couchbase-cxx-client/third_party/docopt/main.cpp +16 -0
- package/deps/couchbase-cxx-client/third_party/docopt/run_testcase.cpp +40 -0
- package/deps/couchbase-cxx-client/third_party/docopt/run_tests.py +72 -0
- package/deps/couchbase-cxx-client/third_party/docopt/testcases.docopt +957 -0
- package/deps/couchbase-cxx-client/tools/CMakeLists.txt +14 -0
- package/deps/couchbase-cxx-client/tools/cbc.cxx +65 -0
- package/deps/couchbase-cxx-client/tools/command.hxx +31 -0
- package/deps/couchbase-cxx-client/tools/command_registry.cxx +43 -0
- package/deps/couchbase-cxx-client/tools/command_registry.hxx +39 -0
- package/deps/couchbase-cxx-client/tools/get.cxx +267 -0
- package/deps/couchbase-cxx-client/tools/get.hxx +26 -0
- package/deps/couchbase-cxx-client/tools/query.cxx +441 -0
- package/deps/couchbase-cxx-client/tools/query.hxx +26 -0
- package/deps/couchbase-cxx-client/tools/utils.cxx +418 -0
- package/deps/couchbase-cxx-client/tools/utils.hxx +150 -0
- package/deps/couchbase-cxx-client/tools/version.cxx +82 -0
- package/deps/couchbase-cxx-client/tools/version.hxx +26 -0
- package/dist/authenticators.d.ts +2 -2
- package/dist/authenticators.js +1 -2
- package/dist/binding.d.ts +32 -16
- package/dist/cluster.js +14 -7
- package/dist/collection.d.ts +6 -0
- package/dist/collection.js +8 -0
- package/dist/queryexecutor.js +1 -1
- package/dist/queryindexmanager.d.ts +100 -4
- package/dist/queryindexmanager.js +344 -118
- package/dist/transactions.js +0 -2
- package/package.json +1 -1
- package/src/connection.cpp +2 -0
- package/src/connection.hpp +1 -0
- package/src/connection_autogen.cpp +16 -0
- package/src/jstocbpp_autogen.hpp +93 -23
- package/src/jstocbpp_basic.hpp +24 -0
- package/src/jstocbpp_transactions.hpp +0 -8
- package/tools/gen-bindings-js.js +1 -0
- package/tools/gen-bindings-json.py +4 -2
- package/deps/couchbase-cxx-client/core/transactions/logging.cxx +0 -107
@@ -57,9 +57,10 @@ attempt_context_impl::attempt_context_impl(transaction_context& transaction_ctx)
|
|
57
57
|
{
|
58
58
|
// put a new transaction_attempt in the context...
|
59
59
|
overall_.add_attempt();
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this,
|
61
|
+
"added new attempt, state {}, expiration in {}ms",
|
62
|
+
attempt_state_name(state()),
|
63
|
+
std::chrono::duration_cast<std::chrono::milliseconds>(overall_.remaining()).count());
|
63
64
|
}
|
64
65
|
|
65
66
|
attempt_context_impl::~attempt_context_impl() = default;
|
@@ -73,11 +74,11 @@ attempt_context_impl::check_and_handle_blocking_transactions(const transaction_g
|
|
73
74
|
// Check not just writing the same doc twice in the same transaction
|
74
75
|
// NOTE: we check the transaction rather than attempt id. This is to handle [RETRY-ERR-AMBIG-REPLACE].
|
75
76
|
if (doc.links().staged_transaction_id().value() == transaction_id()) {
|
76
|
-
|
77
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "doc {} has been written by this transaction, ok to continue", doc.id());
|
77
78
|
return cb(std::nullopt);
|
78
79
|
}
|
79
80
|
if (doc.links().atr_id() && doc.links().atr_bucket_name() && doc.links().staged_attempt_id()) {
|
80
|
-
|
81
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "doc {} in another txn, checking atr...", doc.id());
|
81
82
|
auto err = forward_compat::check(stage, doc.links().forward_compat());
|
82
83
|
if (err) {
|
83
84
|
return cb(err);
|
@@ -85,10 +86,11 @@ attempt_context_impl::check_and_handle_blocking_transactions(const transaction_g
|
|
85
86
|
exp_delay delay(std::chrono::milliseconds(50), std::chrono::milliseconds(500), std::chrono::seconds(1));
|
86
87
|
return check_atr_entry_for_blocking_document(doc, delay, std::move(cb));
|
87
88
|
}
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
89
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this,
|
90
|
+
"doc {} is in another transaction {}, but doesn't have enough info to check the atr. "
|
91
|
+
"probably a bug, proceeding to overwrite",
|
92
|
+
doc.id(),
|
93
|
+
*doc.links().staged_attempt_id());
|
92
94
|
}
|
93
95
|
return cb(std::nullopt);
|
94
96
|
}
|
@@ -300,11 +302,11 @@ attempt_context_impl::replace_raw(const transaction_get_result& document, const
|
|
300
302
|
transaction_operation_failed(FAIL_DOC_NOT_FOUND, "can't replace empty doc")
|
301
303
|
.cause(external_exception::DOCUMENT_NOT_FOUND_EXCEPTION));
|
302
304
|
}
|
303
|
-
|
305
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "replacing {} with {}", document, to_string(content));
|
304
306
|
check_if_done(cb);
|
305
307
|
staged_mutation* existing_sm = staged_mutations_->find_any(document.id());
|
306
308
|
if (existing_sm != nullptr && existing_sm->type() == staged_mutation_type::REMOVE) {
|
307
|
-
|
309
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "found existing REMOVE of {} while replacing", document);
|
308
310
|
return op_completed_with_error(
|
309
311
|
std::move(cb),
|
310
312
|
transaction_operation_failed(FAIL_DOC_NOT_FOUND,
|
@@ -334,7 +336,7 @@ attempt_context_impl::replace_raw(const transaction_get_result& document, const
|
|
334
336
|
return op_completed_with_error(std::move(cb), *e2);
|
335
337
|
}
|
336
338
|
if (existing_sm != nullptr && existing_sm->type() == staged_mutation_type::INSERT) {
|
337
|
-
|
339
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "found existing INSERT of {} while replacing", document);
|
338
340
|
exp_delay delay(
|
339
341
|
std::chrono::milliseconds(5), std::chrono::milliseconds(300), overall_.config().expiration_time);
|
340
342
|
create_staged_insert(document.id(), content, existing_sm->doc().cas().value(), delay, std::move(cb));
|
@@ -383,7 +385,8 @@ attempt_context_impl::create_staged_replace(const transaction_get_result& docume
|
|
383
385
|
if (ec) {
|
384
386
|
return error_handler(*ec, "before_staged_replace hook raised error", std::move(cb));
|
385
387
|
}
|
386
|
-
|
388
|
+
CB_ATTEMPT_CTX_LOG_TRACE(
|
389
|
+
this, "about to replace doc {} with cas {} in txn {}", document.id(), document.cas().value(), overall_.transaction_id());
|
387
390
|
overall_.cluster_ref()->execute(
|
388
391
|
req,
|
389
392
|
[this, document = std::move(document), content, cb = std::move(cb), error_handler = std::move(error_handler)](
|
@@ -398,7 +401,7 @@ attempt_context_impl::create_staged_replace(const transaction_get_result& docume
|
|
398
401
|
transaction_get_result out = document;
|
399
402
|
out.cas(resp.cas.value());
|
400
403
|
out.content(content);
|
401
|
-
|
404
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "replace staged content, result {}", out);
|
402
405
|
staged_mutations_->add(staged_mutation(out, content, staged_mutation_type::REPLACE));
|
403
406
|
return op_completed_with_callback(std::move(cb), std::optional<transaction_get_result>(out));
|
404
407
|
});
|
@@ -449,7 +452,7 @@ attempt_context_impl::insert_raw(const core::document_id& id, const std::vector<
|
|
449
452
|
staged_mutation* existing_sm = staged_mutations_->find_any(id);
|
450
453
|
if ((existing_sm != nullptr) &&
|
451
454
|
(existing_sm->type() == staged_mutation_type::INSERT || existing_sm->type() == staged_mutation_type::REPLACE)) {
|
452
|
-
|
455
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "found existing insert or replace of {} while inserting", id);
|
453
456
|
return op_completed_with_error(
|
454
457
|
std::move(cb),
|
455
458
|
transaction_operation_failed(FAIL_DOC_ALREADY_EXISTS, "found existing insert or replace of same document"));
|
@@ -464,7 +467,7 @@ attempt_context_impl::insert_raw(const core::document_id& id, const std::vector<
|
|
464
467
|
return op_completed_with_error(std::move(cb), *err);
|
465
468
|
}
|
466
469
|
if (existing_sm != nullptr && existing_sm->type() == staged_mutation_type::REMOVE) {
|
467
|
-
|
470
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "found existing remove of {} while inserting", id);
|
468
471
|
return create_staged_replace(existing_sm->doc(), content, std::move(cb));
|
469
472
|
}
|
470
473
|
uint64_t cas = 0;
|
@@ -485,7 +488,7 @@ attempt_context_impl::select_atr_if_needed_unlocked(const core::document_id id,
|
|
485
488
|
try {
|
486
489
|
std::unique_lock<std::mutex> lock(mutex_);
|
487
490
|
if (atr_id_) {
|
488
|
-
|
491
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "atr exists, moving on");
|
489
492
|
return cb(std::nullopt);
|
490
493
|
}
|
491
494
|
std::size_t vbucket_id = 0;
|
@@ -500,11 +503,12 @@ attempt_context_impl::select_atr_if_needed_unlocked(const core::document_id id,
|
|
500
503
|
overall_.atr_collection(collection_spec_from_id(id));
|
501
504
|
overall_.atr_id(atr_id_->key());
|
502
505
|
state(attempt_state::NOT_STARTED);
|
503
|
-
|
506
|
+
CB_ATTEMPT_CTX_LOG_TRACE(
|
507
|
+
this, R"(first mutated doc in transaction is "{}" on vbucket {}, so using atr "{}")", id, vbucket_id, atr_id_.value());
|
504
508
|
overall_.cleanup().add_collection({ atr_id_->bucket(), atr_id_->scope(), atr_id_->collection() });
|
505
509
|
set_atr_pending_locked(id, std::move(lock), std::move(cb));
|
506
510
|
} catch (const std::exception& e) {
|
507
|
-
|
511
|
+
CB_ATTEMPT_CTX_LOG_ERROR(this, "unexpected error \"{}\" during select atr if needed", e.what());
|
508
512
|
}
|
509
513
|
}
|
510
514
|
template<typename Handler, typename Delay>
|
@@ -539,15 +543,17 @@ attempt_context_impl::check_atr_entry_for_blocking_document(const transaction_ge
|
|
539
543
|
switch (it->state()) {
|
540
544
|
case attempt_state::COMPLETED:
|
541
545
|
case attempt_state::ROLLED_BACK:
|
542
|
-
|
546
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(
|
547
|
+
this, "existing atr entry can be ignored due to state {}", attempt_state_name(it->state()));
|
543
548
|
return cb(std::nullopt);
|
544
549
|
default:
|
545
|
-
|
550
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(
|
551
|
+
this, "existing atr entry found in state {}, retrying", attempt_state_name(it->state()));
|
546
552
|
}
|
547
553
|
return check_atr_entry_for_blocking_document(doc, delay, std::move(cb));
|
548
554
|
}
|
549
555
|
}
|
550
|
-
|
556
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "no blocking atr entry");
|
551
557
|
return cb(std::nullopt);
|
552
558
|
}
|
553
559
|
// if we are here, there is still a write-write conflict
|
@@ -592,10 +598,10 @@ attempt_context_impl::remove(const transaction_get_result& document, VoidCallbac
|
|
592
598
|
if (check_expiry_pre_commit(STAGE_REMOVE, document.id().key())) {
|
593
599
|
return error_handler(FAIL_EXPIRY, "transaction expired", std::move(cb));
|
594
600
|
}
|
595
|
-
|
601
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "removing {}", document);
|
596
602
|
if (existing_sm != nullptr) {
|
597
603
|
if (existing_sm->type() == staged_mutation_type::REMOVE) {
|
598
|
-
|
604
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "found existing REMOVE of {} while removing", document);
|
599
605
|
return op_completed_with_error(
|
600
606
|
std::move(cb),
|
601
607
|
transaction_operation_failed(FAIL_DOC_NOT_FOUND,
|
@@ -627,7 +633,7 @@ attempt_context_impl::remove(const transaction_get_result& document, VoidCallbac
|
|
627
633
|
if (auto ec = hooks_.before_staged_remove(this, document.id().key())) {
|
628
634
|
return error_handler(*ec, "before_staged_remove hook raised error", std::move(cb));
|
629
635
|
}
|
630
|
-
|
636
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "about to remove doc {} with cas {}", document.id(), document.cas().value());
|
631
637
|
auto req = create_staging_request(document.id(), &document, "remove");
|
632
638
|
req.cas = document.cas();
|
633
639
|
req.access_deleted = document.links().is_deleted();
|
@@ -640,7 +646,8 @@ attempt_context_impl::remove(const transaction_get_result& document, VoidCallbac
|
|
640
646
|
ec = hooks_.after_staged_remove_complete(this, document.id().key());
|
641
647
|
}
|
642
648
|
if (!ec) {
|
643
|
-
|
649
|
+
CB_ATTEMPT_CTX_LOG_TRACE(
|
650
|
+
this, "removed doc {} CAS={}, rc={}", document.id(), resp.cas.value(), resp.ctx.ec().message());
|
644
651
|
// TODO: this copy... can we do better?
|
645
652
|
transaction_get_result new_res = document;
|
646
653
|
new_res.cas(resp.cas.value());
|
@@ -672,7 +679,7 @@ attempt_context_impl::remove_staged_insert(const core::document_id& id, VoidCall
|
|
672
679
|
return op_completed_with_error(std::move(cb), err.retry());
|
673
680
|
}
|
674
681
|
};
|
675
|
-
|
682
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "removing staged insert {}", id);
|
676
683
|
|
677
684
|
if (auto err = hooks_.before_remove_staged_insert(this, id.key()); err) {
|
678
685
|
return error_handler(*err, "before_remove_staged_insert hook returned error", std::move(cb));
|
@@ -701,7 +708,7 @@ attempt_context_impl::remove_staged_insert(const core::document_id& id, VoidCall
|
|
701
708
|
op_completed_with_callback(std::move(cb));
|
702
709
|
return;
|
703
710
|
}
|
704
|
-
|
711
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "remove_staged_insert got error {}", *ec);
|
705
712
|
return error_handler(*ec, resp.ctx.ec().message(), std::move(cb));
|
706
713
|
});
|
707
714
|
}
|
@@ -738,7 +745,7 @@ wrap_query_request(const couchbase::transactions::transaction_query_options& opt
|
|
738
745
|
}
|
739
746
|
|
740
747
|
void
|
741
|
-
attempt_context_impl::query_begin_work(std::function<void(std::exception_ptr)>&& cb)
|
748
|
+
attempt_context_impl::query_begin_work(std::optional<std::string> query_context, std::function<void(std::exception_ptr)>&& cb)
|
742
749
|
{
|
743
750
|
// construct the txn_data and query options for the existing transaction
|
744
751
|
couchbase::transactions::transaction_query_options opts;
|
@@ -784,19 +791,20 @@ attempt_context_impl::query_begin_work(std::function<void(std::exception_ptr)>&&
|
|
784
791
|
}
|
785
792
|
txdata["mutations"] = mutations;
|
786
793
|
std::vector<core::json_string> params;
|
787
|
-
|
794
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "begin_work using txdata: {}", core::utils::json::generate(txdata));
|
788
795
|
wrap_query(BEGIN_WORK,
|
789
796
|
opts,
|
790
797
|
params,
|
791
798
|
txdata,
|
792
799
|
STAGE_QUERY_BEGIN_WORK,
|
793
800
|
false,
|
801
|
+
query_context,
|
794
802
|
[this, cb = std::move(cb)](std::exception_ptr err, core::operations::query_response resp) mutable {
|
795
803
|
if (resp.served_by_node.empty()) {
|
796
|
-
|
804
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "begin_work didn't reach a query node, resetting mode to kv");
|
797
805
|
op_list_.reset_query_mode();
|
798
806
|
} else {
|
799
|
-
|
807
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "begin_work setting query node to {}", resp.served_by_node);
|
800
808
|
op_list_.set_query_node(resp.served_by_node);
|
801
809
|
}
|
802
810
|
// we check for expiry _after_ this call, so we always set the query node if we can.
|
@@ -841,7 +849,8 @@ attempt_context_impl::handle_query_error(const core::operations::query_response&
|
|
841
849
|
}
|
842
850
|
auto tx_resp = couchbase::core::impl::build_transaction_query_result(resp);
|
843
851
|
// TODO: look at ambiguous and unambiguous timeout errors vs the codes, etc...
|
844
|
-
|
852
|
+
CB_ATTEMPT_CTX_LOG_TRACE(
|
853
|
+
this, "handling query error {}, {} errors in meta_data", resp.ctx.ec.message(), resp.meta.errors ? "has" : "no");
|
845
854
|
if (resp.ctx.ec == couchbase::errc::common::ambiguous_timeout || resp.ctx.ec == couchbase::errc::common::unambiguous_timeout) {
|
846
855
|
return std::make_exception_ptr(query_attempt_expired(tx_resp.ctx()));
|
847
856
|
}
|
@@ -860,7 +869,7 @@ attempt_context_impl::handle_query_error(const core::operations::query_response&
|
|
860
869
|
|
861
870
|
// just chose first one, to start with...
|
862
871
|
auto chosen_error = choose_error(errors);
|
863
|
-
|
872
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "chosen query error: {}", jsonify(chosen_error));
|
864
873
|
auto code = chosen_error.at("code").as<uint64_t>();
|
865
874
|
|
866
875
|
// we have a fixed strategy for these errors...
|
@@ -907,7 +916,7 @@ attempt_context_impl::handle_query_error(const core::operations::query_response&
|
|
907
916
|
} else if (raise == std::string("failed_post_commit")) {
|
908
917
|
err.failed_post_commit();
|
909
918
|
} else if (raise != std::string("failed")) {
|
910
|
-
|
919
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "unknown value in raise field: {}, raising failed", raise);
|
911
920
|
}
|
912
921
|
return std::make_exception_ptr(err);
|
913
922
|
}
|
@@ -919,17 +928,19 @@ attempt_context_impl::handle_query_error(const core::operations::query_response&
|
|
919
928
|
void
|
920
929
|
attempt_context_impl::do_query(const std::string& statement,
|
921
930
|
const couchbase::transactions::transaction_query_options& opts,
|
931
|
+
std::optional<std::string> query_context,
|
922
932
|
QueryCallback&& cb)
|
923
933
|
{
|
924
934
|
std::vector<core::json_string> params;
|
925
935
|
tao::json::value txdata;
|
926
|
-
|
936
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "do_query called with statement {}", statement);
|
927
937
|
wrap_query(statement,
|
928
938
|
opts,
|
929
939
|
params,
|
930
940
|
txdata,
|
931
941
|
STAGE_QUERY,
|
932
942
|
true,
|
943
|
+
query_context,
|
933
944
|
[this, cb = std::move(cb)](std::exception_ptr err, core::operations::query_response resp) mutable {
|
934
945
|
if (err) {
|
935
946
|
return op_completed_with_error(std::move(cb), err);
|
@@ -961,6 +972,7 @@ attempt_context_impl::wrap_query(const std::string& statement,
|
|
961
972
|
const tao::json::value& txdata,
|
962
973
|
const std::string& hook_point,
|
963
974
|
bool check_expiry,
|
975
|
+
std::optional<std::string> query_context,
|
964
976
|
std::function<void(std::exception_ptr, core::operations::query_response)>&& cb)
|
965
977
|
{
|
966
978
|
auto req = wrap_query_request(opts, overall_);
|
@@ -972,8 +984,10 @@ attempt_context_impl::wrap_query(const std::string& statement,
|
|
972
984
|
}
|
973
985
|
}
|
974
986
|
// set the query_context, if one has been set, unless this query already has one
|
975
|
-
if (!
|
976
|
-
req.
|
987
|
+
if (!query_context && !query_context_.empty()) {
|
988
|
+
req.query_context = query_context_;
|
989
|
+
} else if (query_context) {
|
990
|
+
req.query_context = query_context;
|
977
991
|
}
|
978
992
|
|
979
993
|
if (check_expiry) {
|
@@ -1003,9 +1017,9 @@ attempt_context_impl::wrap_query(const std::string& statement,
|
|
1003
1017
|
}
|
1004
1018
|
return cb(std::make_exception_ptr(transaction_operation_failed(*ec, "before_query hook raised error")), {});
|
1005
1019
|
}
|
1006
|
-
|
1020
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "http request: {}", dump_request(req));
|
1007
1021
|
overall_.cluster_ref()->execute(req, [this, cb = std::move(cb)](core::operations::query_response resp) mutable {
|
1008
|
-
|
1022
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "response: {} status: {}", resp.ctx.http_body, resp.meta.status);
|
1009
1023
|
if (auto ec = hooks_.after_query(this, resp.ctx.statement)) {
|
1010
1024
|
auto err = std::make_exception_ptr(transaction_operation_failed(*ec, "after_query hook raised error"));
|
1011
1025
|
return cb(err, {});
|
@@ -1017,34 +1031,38 @@ attempt_context_impl::wrap_query(const std::string& statement,
|
|
1017
1031
|
void
|
1018
1032
|
attempt_context_impl::query(const std::string& statement,
|
1019
1033
|
const couchbase::transactions::transaction_query_options& options,
|
1034
|
+
std::optional<std::string> query_context,
|
1020
1035
|
QueryCallback&& cb)
|
1021
1036
|
{
|
1022
1037
|
return cache_error_async(cb, [&]() {
|
1023
1038
|
check_if_done(cb);
|
1024
1039
|
// decrement in_flight, as we just incremented it in cache_error_async.
|
1025
1040
|
op_list_.set_query_mode(
|
1026
|
-
[this, statement, options, cb]() mutable {
|
1027
|
-
// set query context if set
|
1028
|
-
if (
|
1041
|
+
[this, statement, options, query_context, cb]() mutable {
|
1042
|
+
// set query context if set
|
1043
|
+
if (query_context) {
|
1029
1044
|
query_context_ = query_context.value();
|
1030
1045
|
}
|
1031
|
-
query_begin_work(
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1046
|
+
query_begin_work(query_context,
|
1047
|
+
[this, statement, query_context, options, cb = std::move(cb)](std::exception_ptr err) mutable {
|
1048
|
+
if (err) {
|
1049
|
+
return op_completed_with_error(std::move(cb), err);
|
1050
|
+
}
|
1051
|
+
return do_query(statement, options, query_context, std::move(cb));
|
1052
|
+
});
|
1037
1053
|
},
|
1038
|
-
[this, statement, options, cb]() mutable { return do_query(statement, options, std::move(cb)); });
|
1054
|
+
[this, statement, options, query_context, cb]() mutable { return do_query(statement, options, query_context, std::move(cb)); });
|
1039
1055
|
});
|
1040
1056
|
}
|
1041
1057
|
|
1042
1058
|
core::operations::query_response
|
1043
|
-
attempt_context_impl::do_core_query(const std::string& statement,
|
1059
|
+
attempt_context_impl::do_core_query(const std::string& statement,
|
1060
|
+
const couchbase::transactions::transaction_query_options& options,
|
1061
|
+
std::optional<std::string> query_context)
|
1044
1062
|
{
|
1045
1063
|
auto barrier = std::make_shared<std::promise<core::operations::query_response>>();
|
1046
1064
|
auto f = barrier->get_future();
|
1047
|
-
query(statement, options, [barrier](std::exception_ptr err, std::optional<core::operations::query_response> resp) {
|
1065
|
+
query(statement, options, query_context, [barrier](std::exception_ptr err, std::optional<core::operations::query_response> resp) {
|
1048
1066
|
if (err) {
|
1049
1067
|
return barrier->set_exception(err);
|
1050
1068
|
}
|
@@ -1054,10 +1072,12 @@ attempt_context_impl::do_core_query(const std::string& statement, const couchbas
|
|
1054
1072
|
}
|
1055
1073
|
|
1056
1074
|
couchbase::transactions::transaction_query_result_ptr
|
1057
|
-
attempt_context_impl::do_public_query(const std::string& statement,
|
1075
|
+
attempt_context_impl::do_public_query(const std::string& statement,
|
1076
|
+
const couchbase::transactions::transaction_query_options& opts,
|
1077
|
+
std::optional<std::string> query_context)
|
1058
1078
|
{
|
1059
1079
|
try {
|
1060
|
-
auto result = do_core_query(statement, opts);
|
1080
|
+
auto result = do_core_query(statement, opts, query_context);
|
1061
1081
|
return std::make_shared<couchbase::transactions::transaction_query_result>(core::impl::build_transaction_query_result(result));
|
1062
1082
|
} catch (const transaction_operation_failed& e) {
|
1063
1083
|
return std::make_shared<couchbase::transactions::transaction_query_result>(e.get_error_ctx());
|
@@ -1110,6 +1130,7 @@ attempt_context_impl::get_with_query(const core::document_id& id, bool optional,
|
|
1110
1130
|
make_kv_txdata(),
|
1111
1131
|
STAGE_QUERY_KV_GET,
|
1112
1132
|
true,
|
1133
|
+
{},
|
1113
1134
|
[this, id, optional, cb = std::move(cb)](std::exception_ptr err, core::operations::query_response resp) mutable {
|
1114
1135
|
if (resp.ctx.ec == couchbase::errc::key_value::document_not_found) {
|
1115
1136
|
return op_completed_with_callback(std::move(cb), std::optional<transaction_get_result>());
|
@@ -1121,7 +1142,7 @@ attempt_context_impl::get_with_query(const core::document_id& id, bool optional,
|
|
1121
1142
|
return op_completed_with_error(
|
1122
1143
|
std::move(cb), transaction_operation_failed(FAIL_DOC_NOT_FOUND, "document not found"));
|
1123
1144
|
}
|
1124
|
-
|
1145
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "get_with_query got: {}", resp.rows.front());
|
1125
1146
|
transaction_get_result doc(id, core::utils::json::parse(resp.rows.front()));
|
1126
1147
|
return op_completed_with_callback(std::move(cb), std::optional<transaction_get_result>(doc));
|
1127
1148
|
} catch (const std::exception& e) {
|
@@ -1157,6 +1178,7 @@ attempt_context_impl::insert_raw_with_query(const core::document_id& id, const s
|
|
1157
1178
|
make_kv_txdata(),
|
1158
1179
|
STAGE_QUERY_KV_INSERT,
|
1159
1180
|
true,
|
1181
|
+
{},
|
1160
1182
|
[this, id, cb = std::move(cb)](std::exception_ptr err, core::operations::query_response resp) mutable {
|
1161
1183
|
if (err) {
|
1162
1184
|
try {
|
@@ -1175,7 +1197,7 @@ attempt_context_impl::insert_raw_with_query(const core::document_id& id, const s
|
|
1175
1197
|
}
|
1176
1198
|
// make a transaction_get_result from the row...
|
1177
1199
|
try {
|
1178
|
-
|
1200
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "insert_raw_with_query got: {}", resp.rows.front());
|
1179
1201
|
transaction_get_result doc(id, core::utils::json::parse(resp.rows.front()));
|
1180
1202
|
return op_completed_with_callback(std::move(cb), std::optional<transaction_get_result>(doc));
|
1181
1203
|
} catch (const std::exception& e) {
|
@@ -1200,6 +1222,7 @@ attempt_context_impl::replace_raw_with_query(const transaction_get_result& docum
|
|
1200
1222
|
make_kv_txdata(document),
|
1201
1223
|
STAGE_QUERY_KV_REPLACE,
|
1202
1224
|
true,
|
1225
|
+
{},
|
1203
1226
|
[this, id = document.id(), cb = std::move(cb)](std::exception_ptr err, core::operations::query_response resp) mutable {
|
1204
1227
|
if (err) {
|
1205
1228
|
try {
|
@@ -1218,7 +1241,7 @@ attempt_context_impl::replace_raw_with_query(const transaction_get_result& docum
|
|
1218
1241
|
}
|
1219
1242
|
// make a transaction_get_result from the row...
|
1220
1243
|
try {
|
1221
|
-
|
1244
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "replace_raw_with_query got: {}", resp.rows.front());
|
1222
1245
|
transaction_get_result doc(id, core::utils::json::parse(resp.rows.front()));
|
1223
1246
|
return op_completed_with_callback(std::move(cb), std::optional<transaction_get_result>(doc));
|
1224
1247
|
} catch (const std::exception& e) {
|
@@ -1242,6 +1265,7 @@ attempt_context_impl::remove_with_query(const transaction_get_result& document,
|
|
1242
1265
|
make_kv_txdata(document),
|
1243
1266
|
STAGE_QUERY_KV_REMOVE,
|
1244
1267
|
true,
|
1268
|
+
{},
|
1245
1269
|
[this, id = document.id(), cb = std::move(cb)](std::exception_ptr err, core::operations::query_response /* resp */) mutable {
|
1246
1270
|
if (err) {
|
1247
1271
|
try {
|
@@ -1268,7 +1292,7 @@ void
|
|
1268
1292
|
attempt_context_impl::commit_with_query(VoidCallback&& cb)
|
1269
1293
|
{
|
1270
1294
|
core::operations::query_request req;
|
1271
|
-
|
1295
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "commit_with_query called");
|
1272
1296
|
couchbase::transactions::transaction_query_options opts;
|
1273
1297
|
std::vector<core::json_string> params;
|
1274
1298
|
wrap_query(
|
@@ -1278,6 +1302,7 @@ attempt_context_impl::commit_with_query(VoidCallback&& cb)
|
|
1278
1302
|
make_kv_txdata(std::nullopt),
|
1279
1303
|
STAGE_QUERY_COMMIT,
|
1280
1304
|
true,
|
1305
|
+
{},
|
1281
1306
|
[this, cb = std::move(cb)](std::exception_ptr err, core::operations::query_response /* resp */) mutable {
|
1282
1307
|
is_done_ = true;
|
1283
1308
|
if (err) {
|
@@ -1305,7 +1330,7 @@ void
|
|
1305
1330
|
attempt_context_impl::rollback_with_query(VoidCallback&& cb)
|
1306
1331
|
{
|
1307
1332
|
core::operations::query_request req;
|
1308
|
-
|
1333
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "rollback_with_query called");
|
1309
1334
|
couchbase::transactions::transaction_query_options opts;
|
1310
1335
|
std::vector<core::json_string> params;
|
1311
1336
|
wrap_query(ROLLBACK,
|
@@ -1314,6 +1339,7 @@ attempt_context_impl::rollback_with_query(VoidCallback&& cb)
|
|
1314
1339
|
make_kv_txdata(std::nullopt),
|
1315
1340
|
STAGE_QUERY_ROLLBACK,
|
1316
1341
|
true,
|
1342
|
+
{},
|
1317
1343
|
[this, cb = std::move(cb)](std::exception_ptr err, core::operations::query_response /* resp */) mutable {
|
1318
1344
|
is_done_ = true;
|
1319
1345
|
if (err) {
|
@@ -1322,13 +1348,14 @@ attempt_context_impl::rollback_with_query(VoidCallback&& cb)
|
|
1322
1348
|
} catch (const transaction_operation_failed&) {
|
1323
1349
|
return cb(std::current_exception());
|
1324
1350
|
} catch (const query_attempt_not_found& e) {
|
1325
|
-
|
1351
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(
|
1352
|
+
this, "got query_attempt_not_found, assuming query was already rolled back successfullly: {}", e.what());
|
1326
1353
|
} catch (const std::exception& e) {
|
1327
1354
|
return cb(std::make_exception_ptr(transaction_operation_failed(FAIL_OTHER, e.what()).no_rollback()));
|
1328
1355
|
}
|
1329
1356
|
}
|
1330
1357
|
state(attempt_state::ROLLED_BACK);
|
1331
|
-
|
1358
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "rollback successful");
|
1332
1359
|
return cb({});
|
1333
1360
|
});
|
1334
1361
|
}
|
@@ -1358,7 +1385,7 @@ attempt_context_impl::atr_commit(bool ambiguity_resolution_mode)
|
|
1358
1385
|
staged_mutations_->extract_to(prefix, req);
|
1359
1386
|
auto barrier = std::make_shared<std::promise<result>>();
|
1360
1387
|
auto f = barrier->get_future();
|
1361
|
-
|
1388
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "updating atr {}, setting to {}", req.id, attempt_state_name(attempt_state::COMMITTED));
|
1362
1389
|
overall_.cluster_ref()->execute(
|
1363
1390
|
req, [barrier](core::operations::mutate_in_response resp) { barrier->set_value(result::create_from_subdoc_response(resp)); });
|
1364
1391
|
auto res = wrap_operation_future(f, false);
|
@@ -1381,7 +1408,7 @@ attempt_context_impl::atr_commit(bool ambiguity_resolution_mode)
|
|
1381
1408
|
throw out;
|
1382
1409
|
}
|
1383
1410
|
case FAIL_AMBIGUOUS:
|
1384
|
-
|
1411
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "atr_commit got FAIL_AMBIGUOUS, resolving ambiguity...");
|
1385
1412
|
ambiguity_resolution_mode = true;
|
1386
1413
|
throw retry_operation(e.what());
|
1387
1414
|
case FAIL_TRANSIENT:
|
@@ -1427,11 +1454,12 @@ attempt_context_impl::atr_commit(bool ambiguity_resolution_mode)
|
|
1427
1454
|
throw out;
|
1428
1455
|
}
|
1429
1456
|
default: {
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1457
|
+
CB_ATTEMPT_CTX_LOG_ERROR(this,
|
1458
|
+
"failed to commit transaction {}, attempt {}, ambiguity_resolution_mode {}, with error {}",
|
1459
|
+
transaction_id(),
|
1460
|
+
id(),
|
1461
|
+
ambiguity_resolution_mode,
|
1462
|
+
e.what());
|
1435
1463
|
auto out = transaction_operation_failed(ec, e.what());
|
1436
1464
|
if (ambiguity_resolution_mode) {
|
1437
1465
|
out.no_rollback().ambiguous();
|
@@ -1464,7 +1492,7 @@ attempt_context_impl::atr_commit_ambiguity_resolution()
|
|
1464
1492
|
req, [barrier](core::operations::lookup_in_response resp) { barrier->set_value(result::create_from_subdoc_response(resp)); });
|
1465
1493
|
auto res = wrap_operation_future(f);
|
1466
1494
|
auto atr_status_raw = res.values[0].content_as<std::string>();
|
1467
|
-
|
1495
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "atr_commit_ambiguity_resolution read atr state {}", atr_status_raw);
|
1468
1496
|
auto atr_status = attempt_state_value(atr_status_raw);
|
1469
1497
|
switch (atr_status) {
|
1470
1498
|
case attempt_state::COMMITTED:
|
@@ -1510,7 +1538,7 @@ attempt_context_impl::atr_complete()
|
|
1510
1538
|
if (!!(ec = error_if_expired_and_not_in_overtime(STAGE_ATR_COMPLETE, {}))) {
|
1511
1539
|
throw client_error(*ec, "atr_complete threw error");
|
1512
1540
|
}
|
1513
|
-
|
1541
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "removing attempt {} from atr", atr_id_.value());
|
1514
1542
|
std::string prefix(ATR_FIELD_ATTEMPTS + "." + id());
|
1515
1543
|
core::operations::mutate_in_request req{ atr_id_.value() };
|
1516
1544
|
req.specs =
|
@@ -1535,7 +1563,7 @@ attempt_context_impl::atr_complete()
|
|
1535
1563
|
case FAIL_HARD:
|
1536
1564
|
throw transaction_operation_failed(ec, er.what()).no_rollback().failed_post_commit();
|
1537
1565
|
default:
|
1538
|
-
|
1566
|
+
CB_ATTEMPT_CTX_LOG_INFO(this, "ignoring error in atr_complete {}", er.what());
|
1539
1567
|
}
|
1540
1568
|
}
|
1541
1569
|
}
|
@@ -1558,10 +1586,10 @@ attempt_context_impl::commit(VoidCallback&& cb)
|
|
1558
1586
|
void
|
1559
1587
|
attempt_context_impl::commit()
|
1560
1588
|
{
|
1561
|
-
|
1589
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "waiting on ops to finish...");
|
1562
1590
|
op_list_.wait_and_block_ops();
|
1563
1591
|
existing_error(false);
|
1564
|
-
|
1592
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "commit {}", id());
|
1565
1593
|
if (op_list_.get_mode().is_query()) {
|
1566
1594
|
auto barrier = std::make_shared<std::promise<void>>();
|
1567
1595
|
auto f = barrier->get_future();
|
@@ -1579,13 +1607,13 @@ attempt_context_impl::commit()
|
|
1579
1607
|
}
|
1580
1608
|
if (atr_id_ && !atr_id_->key().empty() && !is_done_) {
|
1581
1609
|
retry_op_exp<void>([&]() { atr_commit(false); });
|
1582
|
-
staged_mutations_->commit(
|
1610
|
+
staged_mutations_->commit(this);
|
1583
1611
|
atr_complete();
|
1584
1612
|
is_done_ = true;
|
1585
1613
|
} else {
|
1586
1614
|
// no mutation, no need to commit
|
1587
1615
|
if (!is_done_) {
|
1588
|
-
|
1616
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "calling commit on attempt that has got no mutations, skipping");
|
1589
1617
|
is_done_ = true;
|
1590
1618
|
return;
|
1591
1619
|
} // do not rollback or retry
|
@@ -1629,17 +1657,17 @@ attempt_context_impl::atr_abort()
|
|
1629
1657
|
if (ec) {
|
1630
1658
|
throw client_error(*ec, "after_atr_aborted hook threw error");
|
1631
1659
|
}
|
1632
|
-
|
1660
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "rollback completed atr abort phase");
|
1633
1661
|
} catch (const client_error& e) {
|
1634
1662
|
auto ec = e.ec();
|
1635
|
-
|
1663
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "atr_abort got {} {}", ec, e.what());
|
1636
1664
|
if (expiry_overtime_mode_.load()) {
|
1637
|
-
|
1665
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "atr_abort got error \"{}\" while in overtime mode", e.what());
|
1638
1666
|
throw transaction_operation_failed(FAIL_EXPIRY, std::string("expired in atr_abort with {} ") + e.what())
|
1639
1667
|
.no_rollback()
|
1640
1668
|
.expired();
|
1641
1669
|
}
|
1642
|
-
|
1670
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "atr_abort got error {}", ec);
|
1643
1671
|
switch (ec) {
|
1644
1672
|
case FAIL_EXPIRY:
|
1645
1673
|
expiry_overtime_mode_ = true;
|
@@ -1692,28 +1720,28 @@ attempt_context_impl::atr_rollback_complete()
|
|
1692
1720
|
} catch (const client_error& e) {
|
1693
1721
|
auto ec = e.ec();
|
1694
1722
|
if (expiry_overtime_mode_.load()) {
|
1695
|
-
|
1723
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "atr_rollback_complete error while in overtime mode {}", e.what());
|
1696
1724
|
throw transaction_operation_failed(FAIL_EXPIRY, std::string("expired in atr_rollback_complete with {} ") + e.what())
|
1697
1725
|
.no_rollback()
|
1698
1726
|
.expired();
|
1699
1727
|
}
|
1700
|
-
|
1728
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "atr_rollback_complete got error {}", ec);
|
1701
1729
|
switch (ec) {
|
1702
1730
|
case FAIL_DOC_NOT_FOUND:
|
1703
1731
|
case FAIL_PATH_NOT_FOUND:
|
1704
|
-
|
1732
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "atr {} not found, ignoring", atr_id_->key());
|
1705
1733
|
is_done_ = true;
|
1706
1734
|
break;
|
1707
1735
|
case FAIL_ATR_FULL:
|
1708
|
-
|
1736
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "atr {} full!", atr_id_->key());
|
1709
1737
|
throw retry_operation(e.what());
|
1710
1738
|
case FAIL_HARD:
|
1711
1739
|
throw transaction_operation_failed(ec, e.what()).no_rollback();
|
1712
1740
|
case FAIL_EXPIRY:
|
1713
|
-
|
1741
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "timed out writing atr {}", atr_id_->key());
|
1714
1742
|
throw transaction_operation_failed(ec, e.what()).no_rollback().expired();
|
1715
1743
|
default:
|
1716
|
-
|
1744
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "retrying atr_rollback_complete");
|
1717
1745
|
throw retry_operation(e.what());
|
1718
1746
|
}
|
1719
1747
|
}
|
@@ -1743,7 +1771,7 @@ void
|
|
1743
1771
|
attempt_context_impl::rollback()
|
1744
1772
|
{
|
1745
1773
|
op_list_.wait_and_block_ops();
|
1746
|
-
|
1774
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "rolling back {}", id());
|
1747
1775
|
if (op_list_.get_mode().is_query()) {
|
1748
1776
|
auto barrier = std::make_shared<std::promise<void>>();
|
1749
1777
|
auto f = barrier->get_future();
|
@@ -1760,13 +1788,13 @@ attempt_context_impl::rollback()
|
|
1760
1788
|
check_expiry_during_commit_or_rollback(STAGE_ROLLBACK, std::nullopt);
|
1761
1789
|
if (!atr_id_ || atr_id_->key().empty() || state() == attempt_state::NOT_STARTED) {
|
1762
1790
|
// TODO: check this, but if we try to rollback an empty txn, we should prevent a subsequent commit
|
1763
|
-
|
1791
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "rollback called on txn with no mutations");
|
1764
1792
|
is_done_ = true;
|
1765
1793
|
return;
|
1766
1794
|
}
|
1767
1795
|
if (is_done()) {
|
1768
1796
|
std::string msg("Transaction already done, cannot rollback");
|
1769
|
-
|
1797
|
+
CB_ATTEMPT_CTX_LOG_ERROR(this, msg);
|
1770
1798
|
// need to raise a FAIL_OTHER which is not retryable or rollback-able
|
1771
1799
|
throw transaction_operation_failed(FAIL_OTHER, msg).no_rollback();
|
1772
1800
|
}
|
@@ -1774,14 +1802,14 @@ attempt_context_impl::rollback()
|
|
1774
1802
|
// (1) atr_abort
|
1775
1803
|
retry_op_exp<void>([&]() { atr_abort(); });
|
1776
1804
|
// (2) rollback staged mutations
|
1777
|
-
staged_mutations_->rollback(
|
1778
|
-
|
1805
|
+
staged_mutations_->rollback(this);
|
1806
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "rollback completed unstaging docs");
|
1779
1807
|
|
1780
1808
|
// (3) atr_rollback
|
1781
1809
|
retry_op_exp<void>([&]() { atr_rollback_complete(); });
|
1782
1810
|
} catch (const client_error& e) {
|
1783
1811
|
error_class ec = e.ec();
|
1784
|
-
|
1812
|
+
CB_ATTEMPT_CTX_LOG_ERROR(this, "rollback transaction {}, attempt {} fail with error {}", transaction_id(), id(), e.what());
|
1785
1813
|
if (ec == FAIL_HARD) {
|
1786
1814
|
throw transaction_operation_failed(ec, e.what()).no_rollback();
|
1787
1815
|
}
|
@@ -1794,10 +1822,10 @@ attempt_context_impl::has_expired_client_side(std::string place, std::optional<c
|
|
1794
1822
|
bool over = overall_.has_expired_client_side();
|
1795
1823
|
bool hook = hooks_.has_expired_client_side(this, place, doc_id);
|
1796
1824
|
if (over) {
|
1797
|
-
|
1825
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "{} expired in {}", id(), place);
|
1798
1826
|
}
|
1799
1827
|
if (hook) {
|
1800
|
-
|
1828
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "{} fake expiry in {}", id(), place);
|
1801
1829
|
}
|
1802
1830
|
return over || hook;
|
1803
1831
|
}
|
@@ -1806,7 +1834,8 @@ bool
|
|
1806
1834
|
attempt_context_impl::check_expiry_pre_commit(std::string stage, std::optional<const std::string> doc_id)
|
1807
1835
|
{
|
1808
1836
|
if (has_expired_client_side(stage, std::move(doc_id))) {
|
1809
|
-
|
1837
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(
|
1838
|
+
this, "{} has expired in stage {}, entering expiry-overtime mode - will make one attempt to rollback", id(), stage);
|
1810
1839
|
|
1811
1840
|
// [EXP-ROLLBACK] Combo of setting this mode and throwing AttemptExpired will result in an attempt to rollback, which will
|
1812
1841
|
// ignore expiry, and bail out if anything fails
|
@@ -1820,11 +1849,11 @@ std::optional<error_class>
|
|
1820
1849
|
attempt_context_impl::error_if_expired_and_not_in_overtime(const std::string& stage, std::optional<const std::string> doc_id)
|
1821
1850
|
{
|
1822
1851
|
if (expiry_overtime_mode_.load()) {
|
1823
|
-
|
1852
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "not doing expired check in {} as already in expiry-overtime", stage);
|
1824
1853
|
return {};
|
1825
1854
|
}
|
1826
1855
|
if (has_expired_client_side(stage, std::move(doc_id))) {
|
1827
|
-
|
1856
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "expired in {}", stage);
|
1828
1857
|
return FAIL_EXPIRY;
|
1829
1858
|
}
|
1830
1859
|
return {};
|
@@ -1836,11 +1865,12 @@ attempt_context_impl::check_expiry_during_commit_or_rollback(const std::string&
|
|
1836
1865
|
// [EXP-COMMIT-OVERTIME]
|
1837
1866
|
if (!expiry_overtime_mode_.load()) {
|
1838
1867
|
if (has_expired_client_side(stage, std::move(doc_id))) {
|
1839
|
-
|
1868
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(
|
1869
|
+
this, "{} has expired in stage {}, entering expiry-overtime mode (one attempt to complete commit)", id(), stage);
|
1840
1870
|
expiry_overtime_mode_ = true;
|
1841
1871
|
}
|
1842
1872
|
} else {
|
1843
|
-
|
1873
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "{} ignoring expiry in stage {} as in expiry-overtime mode", id(), stage);
|
1844
1874
|
}
|
1845
1875
|
}
|
1846
1876
|
template<typename Handler>
|
@@ -1859,7 +1889,7 @@ attempt_context_impl::set_atr_pending_locked(const core::document_id& id, std::u
|
|
1859
1889
|
auto error_handler =
|
1860
1890
|
[this, &lock](error_class ec, const std::string& message, const core::document_id& doc_id, Handler&& fn) mutable {
|
1861
1891
|
transaction_operation_failed err(ec, message);
|
1862
|
-
|
1892
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "got {} trying to set atr to pending", message);
|
1863
1893
|
if (expiry_overtime_mode_.load()) {
|
1864
1894
|
return fn(err.no_rollback().expired());
|
1865
1895
|
}
|
@@ -1877,7 +1907,7 @@ attempt_context_impl::set_atr_pending_locked(const core::document_id& id, std::u
|
|
1877
1907
|
// Retry just this
|
1878
1908
|
overall_.retry_delay();
|
1879
1909
|
// keep it locked!
|
1880
|
-
|
1910
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "got {}, retrying set atr pending", ec);
|
1881
1911
|
return set_atr_pending_locked(doc_id, std::move(lock), std::move(fn));
|
1882
1912
|
case FAIL_TRANSIENT:
|
1883
1913
|
// Retry txn
|
@@ -1891,7 +1921,7 @@ attempt_context_impl::set_atr_pending_locked(const core::document_id& id, std::u
|
|
1891
1921
|
if (auto ec = hooks_.before_atr_pending(this); ec) {
|
1892
1922
|
return error_handler(*ec, "before_atr_pending hook raised error", id, std::forward<Handler>(fn));
|
1893
1923
|
}
|
1894
|
-
|
1924
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "updating atr {}", atr_id_.value());
|
1895
1925
|
|
1896
1926
|
// FIXME: do we need to capture "now" here?
|
1897
1927
|
// std::chrono::time_point<std::chrono::steady_clock> now = std::chrono::steady_clock::now();
|
@@ -1935,7 +1965,7 @@ attempt_context_impl::set_atr_pending_locked(const core::document_id& id, std::u
|
|
1935
1965
|
}
|
1936
1966
|
if (!ec) {
|
1937
1967
|
state(attempt_state::PENDING);
|
1938
|
-
|
1968
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "set ATR {} to Pending, got CAS (start time) {}", atr_id_.value(), resp.cas.value());
|
1939
1969
|
return fn(std::nullopt);
|
1940
1970
|
}
|
1941
1971
|
return error_handler(*ec,
|
@@ -1945,7 +1975,7 @@ attempt_context_impl::set_atr_pending_locked(const core::document_id& id, std::u
|
|
1945
1975
|
});
|
1946
1976
|
}
|
1947
1977
|
} catch (const std::exception& e) {
|
1948
|
-
|
1978
|
+
CB_ATTEMPT_CTX_LOG_ERROR(this, "unexpected error setting atr pending {}", e.what());
|
1949
1979
|
return fn(transaction_operation_failed(FAIL_OTHER, "unexpected error setting atr pending"));
|
1950
1980
|
}
|
1951
1981
|
}
|
@@ -1986,13 +2016,13 @@ attempt_context_impl::do_get(const core::document_id& id, const std::optional<st
|
|
1986
2016
|
|
1987
2017
|
staged_mutation* own_write = check_for_own_write(id);
|
1988
2018
|
if (own_write) {
|
1989
|
-
|
2019
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "found own-write of mutated doc {}", id);
|
1990
2020
|
return cb(std::nullopt, std::nullopt, transaction_get_result::create_from(own_write->doc(), own_write->content()));
|
1991
2021
|
}
|
1992
2022
|
staged_mutation* own_remove = staged_mutations_->find_remove(id);
|
1993
2023
|
if (own_remove) {
|
1994
2024
|
auto msg = fmt::format("found own-write of removed doc {}", id);
|
1995
|
-
|
2025
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, msg);
|
1996
2026
|
return cb(FAIL_DOC_NOT_FOUND, msg, std::nullopt);
|
1997
2027
|
}
|
1998
2028
|
|
@@ -2010,11 +2040,12 @@ attempt_context_impl::do_get(const core::document_id& id, const std::optional<st
|
|
2010
2040
|
}
|
2011
2041
|
if (!ec) {
|
2012
2042
|
if (doc->links().is_document_in_transaction()) {
|
2013
|
-
|
2043
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(
|
2044
|
+
this, "doc {} in transaction, resolving_missing_atr_entry={}", *doc, resolving_missing_atr_entry.value_or("-"));
|
2014
2045
|
|
2015
2046
|
if (resolving_missing_atr_entry.has_value() &&
|
2016
2047
|
resolving_missing_atr_entry.value() == doc->links().staged_attempt_id()) {
|
2017
|
-
|
2048
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "doc is in lost pending transaction");
|
2018
2049
|
|
2019
2050
|
if (doc->links().is_document_being_inserted()) {
|
2020
2051
|
// this document is being inserted, so should not be visible yet
|
@@ -2072,8 +2103,9 @@ attempt_context_impl::do_get(const core::document_id& id, const std::optional<st
|
|
2072
2103
|
}
|
2073
2104
|
} else {
|
2074
2105
|
// failed to get the ATR entry
|
2075
|
-
|
2076
|
-
|
2106
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this,
|
2107
|
+
"could not get ATR entry, checking again with {}",
|
2108
|
+
doc->links().staged_attempt_id().value_or("-"));
|
2077
2109
|
return do_get(id, doc->links().staged_attempt_id(), cb);
|
2078
2110
|
}
|
2079
2111
|
if (ignore_doc) {
|
@@ -2083,13 +2115,14 @@ attempt_context_impl::do_get(const core::document_id& id, const std::optional<st
|
|
2083
2115
|
|
2084
2116
|
} else {
|
2085
2117
|
// failed to get the ATR
|
2086
|
-
|
2118
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(
|
2119
|
+
this, "could not get ATR, checking again with {}", doc->links().staged_attempt_id().value_or("-"));
|
2087
2120
|
return do_get(id, doc->links().staged_attempt_id(), cb);
|
2088
2121
|
}
|
2089
2122
|
});
|
2090
2123
|
} else {
|
2091
2124
|
if (doc->links().is_deleted()) {
|
2092
|
-
|
2125
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "doc not in txn, and is_deleted, so not returning it.");
|
2093
2126
|
// doc has been deleted, not in txn, so don't return it
|
2094
2127
|
return cb(std::nullopt, std::nullopt, std::nullopt);
|
2095
2128
|
}
|
@@ -2138,7 +2171,7 @@ attempt_context_impl::get_doc(
|
|
2138
2171
|
overall_.cluster_ref()->execute(req, [this, id, cb = std::move(cb)](core::operations::lookup_in_response resp) {
|
2139
2172
|
auto ec = error_class_from_response(resp);
|
2140
2173
|
if (ec) {
|
2141
|
-
|
2174
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "get_doc got error {} : {}", resp.ctx.ec().message(), *ec);
|
2142
2175
|
switch (*ec) {
|
2143
2176
|
case FAIL_PATH_NOT_FOUND:
|
2144
2177
|
return cb(*ec, resp.ctx.ec().message(), transaction_get_result::create_from(resp));
|
@@ -2164,7 +2197,7 @@ attempt_context_impl::create_staged_insert_error_handler(const core::document_id
|
|
2164
2197
|
error_class ec,
|
2165
2198
|
const std::string& message)
|
2166
2199
|
{
|
2167
|
-
|
2200
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "create_staged_insert got error class {}: {}", ec, message);
|
2168
2201
|
if (expiry_overtime_mode_.load()) {
|
2169
2202
|
return op_completed_with_error(std::forward<Handler>(cb), transaction_operation_failed(FAIL_EXPIRY, "attempt timed out").expired());
|
2170
2203
|
}
|
@@ -2176,7 +2209,7 @@ attempt_context_impl::create_staged_insert_error_handler(const core::document_id
|
|
2176
2209
|
return op_completed_with_error(std::forward<Handler>(cb),
|
2177
2210
|
transaction_operation_failed(ec, "transient error in insert").retry());
|
2178
2211
|
case FAIL_AMBIGUOUS:
|
2179
|
-
|
2212
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "FAIL_AMBIGUOUS in create_staged_insert, retrying");
|
2180
2213
|
delay();
|
2181
2214
|
return create_staged_insert(id, content, cas, delay, std::forward<Handler>(cb));
|
2182
2215
|
case FAIL_OTHER:
|
@@ -2187,9 +2220,10 @@ attempt_context_impl::create_staged_insert_error_handler(const core::document_id
|
|
2187
2220
|
case FAIL_DOC_ALREADY_EXISTS:
|
2188
2221
|
case FAIL_CAS_MISMATCH: {
|
2189
2222
|
// special handling for doc already existing
|
2190
|
-
|
2223
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "found existing doc {}, may still be able to insert", id);
|
2191
2224
|
auto error_handler = [this, id, content](error_class ec2, const std::string& err_message, Handler&& cb) mutable {
|
2192
|
-
|
2225
|
+
CB_ATTEMPT_CTX_LOG_TRACE(
|
2226
|
+
this, "after a CAS_MISMATCH or DOC_ALREADY_EXISTS, then got error {} in create_staged_insert", ec2);
|
2193
2227
|
if (expiry_overtime_mode_.load()) {
|
2194
2228
|
return op_completed_with_error(std::move(cb), transaction_operation_failed(FAIL_EXPIRY, "attempt timed out").expired());
|
2195
2229
|
}
|
@@ -2217,10 +2251,11 @@ attempt_context_impl::create_staged_insert_error_handler(const core::document_id
|
|
2217
2251
|
std::optional<error_class> ec3, std::optional<std::string> err_message, std::optional<transaction_get_result> doc) mutable {
|
2218
2252
|
if (!ec3) {
|
2219
2253
|
if (doc) {
|
2220
|
-
|
2221
|
-
|
2222
|
-
|
2223
|
-
|
2254
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this,
|
2255
|
+
"document {} exists, is_in_transaction {}, is_deleted {} ",
|
2256
|
+
doc->id(),
|
2257
|
+
doc->links().is_document_in_transaction(),
|
2258
|
+
doc->links().is_deleted());
|
2224
2259
|
|
2225
2260
|
if (auto err = forward_compat::check(forward_compat_stage::WWC_INSERTING_GET, doc->links().forward_compat());
|
2226
2261
|
err) {
|
@@ -2228,13 +2263,14 @@ attempt_context_impl::create_staged_insert_error_handler(const core::document_id
|
|
2228
2263
|
}
|
2229
2264
|
if (!doc->links().is_document_in_transaction() && doc->links().is_deleted()) {
|
2230
2265
|
// it is just a deleted doc, so we are ok. Let's try again, but with the cas
|
2231
|
-
|
2266
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(
|
2267
|
+
this, "create staged insert found existing deleted doc, retrying with cas {}", doc->cas().value());
|
2232
2268
|
delay();
|
2233
2269
|
return create_staged_insert(id, content, doc->cas().value(), delay, std::forward<Handler>(cb));
|
2234
2270
|
}
|
2235
2271
|
if (!doc->links().is_document_in_transaction()) {
|
2236
2272
|
// doc was inserted outside txn elsewhere
|
2237
|
-
|
2273
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "doc {} not in txn - was inserted outside txn", id);
|
2238
2274
|
return op_completed_with_error(
|
2239
2275
|
std::forward<Handler>(cb),
|
2240
2276
|
document_exists({ couchbase::errc::transaction_op::document_exists_exception, key_value_error_context() }));
|
@@ -2254,13 +2290,14 @@ attempt_context_impl::create_staged_insert_error_handler(const core::document_id
|
|
2254
2290
|
if (err) {
|
2255
2291
|
return op_completed_with_error(std::move(cb), *err);
|
2256
2292
|
}
|
2257
|
-
|
2293
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(
|
2294
|
+
this, "doc ok to overwrite, retrying create_staged_insert with cas {}", doc->cas().value());
|
2258
2295
|
delay();
|
2259
2296
|
return create_staged_insert(id, content, doc->cas().value(), delay, std::forward<Handler>(cb));
|
2260
2297
|
});
|
2261
2298
|
} else {
|
2262
2299
|
// no doc now, just retry entire txn
|
2263
|
-
|
2300
|
+
CB_ATTEMPT_CTX_LOG_TRACE(this, "got {} from get_doc in exists during staged insert", *ec3);
|
2264
2301
|
return op_completed_with_error(
|
2265
2302
|
std::move(cb),
|
2266
2303
|
transaction_operation_failed(FAIL_DOC_NOT_FOUND, "insert failed as the doc existed, but now seems to not exist")
|
@@ -2295,7 +2332,7 @@ attempt_context_impl::create_staged_insert(const core::document_id& id,
|
|
2295
2332
|
return create_staged_insert_error_handler(
|
2296
2333
|
id, content, cas, std::forward<Delay>(delay), std::forward<Handler>(cb), *ec, "before_staged_insert hook threw error");
|
2297
2334
|
}
|
2298
|
-
|
2335
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "about to insert staged doc {} with cas {}", id, cas);
|
2299
2336
|
auto req = create_staging_request(id, nullptr, "insert", content);
|
2300
2337
|
req.access_deleted = true;
|
2301
2338
|
req.create_as_deleted = true;
|
@@ -2311,7 +2348,7 @@ attempt_context_impl::create_staged_insert(const core::document_id& id,
|
|
2311
2348
|
id, content, cas, std::forward<Delay>(delay), std::forward<Handler>(cb), *ec, "after_staged_insert hook threw error");
|
2312
2349
|
}
|
2313
2350
|
if (!resp.ctx.ec()) {
|
2314
|
-
|
2351
|
+
CB_ATTEMPT_CTX_LOG_DEBUG(this, "inserted doc {} CAS={}, {}", id, resp.cas.value(), resp.ctx.ec().message());
|
2315
2352
|
|
2316
2353
|
// TODO: clean this up (do most of this in transactions_document(...))
|
2317
2354
|
transaction_links links(atr_id_->key(),
|