couchbase 4.2.1 → 4.2.2
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/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(),
|