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
@@ -151,9 +151,9 @@ staged_mutation_queue::iterate(std::function<void(staged_mutation&)> op)
|
|
151
151
|
}
|
152
152
|
|
153
153
|
void
|
154
|
-
staged_mutation_queue::commit(attempt_context_impl
|
154
|
+
staged_mutation_queue::commit(attempt_context_impl* ctx)
|
155
155
|
{
|
156
|
-
ctx
|
156
|
+
CB_ATTEMPT_CTX_LOG_TRACE(ctx, "staged mutations committing...");
|
157
157
|
std::lock_guard<std::mutex> lock(mutex_);
|
158
158
|
for (auto& item : queue_) {
|
159
159
|
switch (item.type()) {
|
@@ -169,7 +169,7 @@ staged_mutation_queue::commit(attempt_context_impl& ctx)
|
|
169
169
|
}
|
170
170
|
|
171
171
|
void
|
172
|
-
staged_mutation_queue::rollback(attempt_context_impl
|
172
|
+
staged_mutation_queue::rollback(attempt_context_impl* ctx)
|
173
173
|
{
|
174
174
|
std::lock_guard<std::mutex> lock(mutex_);
|
175
175
|
for (auto& item : queue_) {
|
@@ -186,15 +186,15 @@ staged_mutation_queue::rollback(attempt_context_impl& ctx)
|
|
186
186
|
}
|
187
187
|
|
188
188
|
void
|
189
|
-
staged_mutation_queue::rollback_insert(attempt_context_impl
|
189
|
+
staged_mutation_queue::rollback_insert(attempt_context_impl* ctx, const staged_mutation& item)
|
190
190
|
{
|
191
191
|
try {
|
192
|
-
ctx
|
193
|
-
auto ec = ctx
|
192
|
+
CB_ATTEMPT_CTX_LOG_TRACE(ctx, "rolling back staged insert for {} with cas {}", item.doc().id(), item.doc().cas().value());
|
193
|
+
auto ec = ctx->error_if_expired_and_not_in_overtime(STAGE_DELETE_INSERTED, item.doc().id().key());
|
194
194
|
if (ec) {
|
195
195
|
throw client_error(*ec, "expired in rollback and not in overtime mode");
|
196
196
|
}
|
197
|
-
ec = ctx
|
197
|
+
ec = ctx->hooks_.before_rollback_delete_inserted(ctx, item.doc().id().key());
|
198
198
|
if (ec) {
|
199
199
|
throw client_error(*ec, "before_rollback_delete_insert hook threw error");
|
200
200
|
}
|
@@ -206,21 +206,21 @@ staged_mutation_queue::rollback_insert(attempt_context_impl& ctx, const staged_m
|
|
206
206
|
.specs();
|
207
207
|
req.access_deleted = true;
|
208
208
|
req.cas = item.doc().cas();
|
209
|
-
wrap_durable_request(req, ctx
|
209
|
+
wrap_durable_request(req, ctx->overall_.config());
|
210
210
|
auto barrier = std::make_shared<std::promise<result>>();
|
211
211
|
auto f = barrier->get_future();
|
212
|
-
ctx
|
212
|
+
ctx->cluster_ref()->execute(
|
213
213
|
req, [barrier](core::operations::mutate_in_response resp) { barrier->set_value(result::create_from_subdoc_response(resp)); });
|
214
214
|
auto res = wrap_operation_future(f);
|
215
|
-
ctx
|
216
|
-
ec = ctx
|
215
|
+
CB_ATTEMPT_CTX_LOG_TRACE(ctx, "rollback result {}", res);
|
216
|
+
ec = ctx->hooks_.after_rollback_delete_inserted(ctx, item.doc().id().key());
|
217
217
|
if (ec) {
|
218
218
|
throw client_error(*ec, "after_rollback_delete_insert hook threw error");
|
219
219
|
}
|
220
220
|
} catch (const client_error& e) {
|
221
221
|
auto ec = e.ec();
|
222
|
-
if (ctx
|
223
|
-
ctx
|
222
|
+
if (ctx->expiry_overtime_mode_.load()) {
|
223
|
+
CB_ATTEMPT_CTX_LOG_TRACE(ctx, "rollback_insert for {} error while in overtime mode {}", item.doc().id(), e.what());
|
224
224
|
throw transaction_operation_failed(FAIL_EXPIRY, std::string("expired while rolling back insert with {} ") + e.what())
|
225
225
|
.no_rollback()
|
226
226
|
.expired();
|
@@ -230,8 +230,8 @@ staged_mutation_queue::rollback_insert(attempt_context_impl& ctx, const staged_m
|
|
230
230
|
case FAIL_CAS_MISMATCH:
|
231
231
|
throw transaction_operation_failed(ec, e.what()).no_rollback();
|
232
232
|
case FAIL_EXPIRY:
|
233
|
-
ctx
|
234
|
-
ctx
|
233
|
+
ctx->expiry_overtime_mode_ = true;
|
234
|
+
CB_ATTEMPT_CTX_LOG_TRACE(ctx, "rollback_insert in expiry overtime mode, retrying...");
|
235
235
|
throw retry_operation("retry rollback_insert");
|
236
236
|
case FAIL_DOC_NOT_FOUND:
|
237
237
|
case FAIL_PATH_NOT_FOUND:
|
@@ -244,15 +244,15 @@ staged_mutation_queue::rollback_insert(attempt_context_impl& ctx, const staged_m
|
|
244
244
|
}
|
245
245
|
|
246
246
|
void
|
247
|
-
staged_mutation_queue::rollback_remove_or_replace(attempt_context_impl
|
247
|
+
staged_mutation_queue::rollback_remove_or_replace(attempt_context_impl* ctx, const staged_mutation& item)
|
248
248
|
{
|
249
249
|
try {
|
250
|
-
ctx
|
251
|
-
auto ec = ctx
|
250
|
+
CB_ATTEMPT_CTX_LOG_TRACE(ctx, "rolling back staged remove/replace for {} with cas {}", item.doc().id(), item.doc().cas().value());
|
251
|
+
auto ec = ctx->error_if_expired_and_not_in_overtime(STAGE_ROLLBACK_DOC, item.doc().id().key());
|
252
252
|
if (ec) {
|
253
253
|
throw client_error(*ec, "expired in rollback_remove_or_replace and not in expiry overtime");
|
254
254
|
}
|
255
|
-
ec = ctx
|
255
|
+
ec = ctx->hooks_.before_doc_rolled_back(ctx, item.doc().id().key());
|
256
256
|
if (ec) {
|
257
257
|
throw client_error(*ec, "before_doc_rolled_back hook threw error");
|
258
258
|
}
|
@@ -263,20 +263,20 @@ staged_mutation_queue::rollback_remove_or_replace(attempt_context_impl& ctx, con
|
|
263
263
|
}
|
264
264
|
.specs();
|
265
265
|
req.cas = item.doc().cas();
|
266
|
-
wrap_durable_request(req, ctx
|
266
|
+
wrap_durable_request(req, ctx->overall_.config());
|
267
267
|
auto barrier = std::make_shared<std::promise<result>>();
|
268
268
|
auto f = barrier->get_future();
|
269
|
-
ctx
|
269
|
+
ctx->cluster_ref()->execute(
|
270
270
|
req, [barrier](core::operations::mutate_in_response resp) { barrier->set_value(result::create_from_subdoc_response(resp)); });
|
271
271
|
auto res = wrap_operation_future(f);
|
272
|
-
ctx
|
273
|
-
ec = ctx
|
272
|
+
CB_ATTEMPT_CTX_LOG_TRACE(ctx, "rollback result {}", res);
|
273
|
+
ec = ctx->hooks_.after_rollback_replace_or_remove(ctx, item.doc().id().key());
|
274
274
|
if (ec) {
|
275
275
|
throw client_error(*ec, "after_rollback_replace_or_remove hook threw error");
|
276
276
|
}
|
277
277
|
} catch (const client_error& e) {
|
278
278
|
auto ec = e.ec();
|
279
|
-
if (ctx
|
279
|
+
if (ctx->expiry_overtime_mode_.load()) {
|
280
280
|
throw transaction_operation_failed(FAIL_EXPIRY, std::string("expired while handling ") + e.what()).no_rollback();
|
281
281
|
}
|
282
282
|
switch (ec) {
|
@@ -285,8 +285,8 @@ staged_mutation_queue::rollback_remove_or_replace(attempt_context_impl& ctx, con
|
|
285
285
|
case FAIL_CAS_MISMATCH:
|
286
286
|
throw transaction_operation_failed(ec, e.what()).no_rollback();
|
287
287
|
case FAIL_EXPIRY:
|
288
|
-
ctx
|
289
|
-
ctx
|
288
|
+
ctx->expiry_overtime_mode_ = true;
|
289
|
+
CB_ATTEMPT_CTX_LOG_TRACE(ctx, "setting expiry overtime mode in {}", STAGE_ROLLBACK_DOC);
|
290
290
|
throw retry_operation("retry rollback_remove_or_replace");
|
291
291
|
case FAIL_PATH_NOT_FOUND:
|
292
292
|
// already cleaned up?
|
@@ -297,29 +297,30 @@ staged_mutation_queue::rollback_remove_or_replace(attempt_context_impl& ctx, con
|
|
297
297
|
}
|
298
298
|
}
|
299
299
|
void
|
300
|
-
staged_mutation_queue::commit_doc(attempt_context_impl
|
300
|
+
staged_mutation_queue::commit_doc(attempt_context_impl* ctx, staged_mutation& item, bool ambiguity_resolution_mode, bool cas_zero_mode)
|
301
301
|
{
|
302
302
|
retry_op<void>([&]() {
|
303
|
-
|
304
|
-
"commit doc {}, cas_zero_mode {}, ambiguity_resolution_mode {}", item.doc().id(), cas_zero_mode, ambiguity_resolution_mode);
|
303
|
+
CB_ATTEMPT_CTX_LOG_TRACE(
|
304
|
+
ctx, "commit doc {}, cas_zero_mode {}, ambiguity_resolution_mode {}", item.doc().id(), cas_zero_mode, ambiguity_resolution_mode);
|
305
305
|
try {
|
306
|
-
ctx
|
307
|
-
auto ec = ctx
|
306
|
+
ctx->check_expiry_during_commit_or_rollback(STAGE_COMMIT_DOC, std::optional<const std::string>(item.doc().id().key()));
|
307
|
+
auto ec = ctx->hooks_.before_doc_committed(ctx, item.doc().id().key());
|
308
308
|
if (ec) {
|
309
309
|
throw client_error(*ec, "before_doc_committed hook threw error");
|
310
310
|
}
|
311
311
|
|
312
312
|
// move staged content into doc
|
313
|
-
|
313
|
+
CB_ATTEMPT_CTX_LOG_TRACE(
|
314
|
+
ctx, "commit doc id {}, content {}, cas {}", item.doc().id(), to_string(item.content()), item.doc().cas().value());
|
314
315
|
|
315
316
|
result res;
|
316
317
|
if (item.type() == staged_mutation_type::INSERT && !cas_zero_mode) {
|
317
318
|
core::operations::insert_request req{ item.doc().id(), item.doc().content() };
|
318
319
|
req.flags = couchbase::codec::codec_flags::json_common_flags;
|
319
|
-
wrap_durable_request(req, ctx
|
320
|
+
wrap_durable_request(req, ctx->overall_.config());
|
320
321
|
auto barrier = std::make_shared<std::promise<result>>();
|
321
322
|
auto f = barrier->get_future();
|
322
|
-
ctx
|
323
|
+
ctx->cluster_ref()->execute(req, [barrier](core::operations::insert_response resp) {
|
323
324
|
barrier->set_value(result::create_from_mutation_response(resp));
|
324
325
|
});
|
325
326
|
res = wrap_operation_future(f);
|
@@ -334,28 +335,28 @@ staged_mutation_queue::commit_doc(attempt_context_impl& ctx, staged_mutation& it
|
|
334
335
|
.specs();
|
335
336
|
req.store_semantics = couchbase::store_semantics::replace;
|
336
337
|
req.cas = couchbase::cas(cas_zero_mode ? 0 : item.doc().cas().value());
|
337
|
-
wrap_durable_request(req, ctx
|
338
|
+
wrap_durable_request(req, ctx->overall_.config());
|
338
339
|
auto barrier = std::make_shared<std::promise<result>>();
|
339
340
|
auto f = barrier->get_future();
|
340
|
-
ctx
|
341
|
+
ctx->cluster_ref()->execute(req, [barrier](core::operations::mutate_in_response resp) {
|
341
342
|
barrier->set_value(result::create_from_subdoc_response(resp));
|
342
343
|
});
|
343
344
|
res = wrap_operation_future(f);
|
344
345
|
}
|
345
|
-
ctx
|
346
|
+
CB_ATTEMPT_CTX_LOG_TRACE(ctx, "commit doc result {}", res);
|
346
347
|
// TODO: mutation tokens
|
347
|
-
ec = ctx
|
348
|
+
ec = ctx->hooks_.after_doc_committed_before_saving_cas(ctx, item.doc().id().key());
|
348
349
|
if (ec) {
|
349
350
|
throw client_error(*ec, "after_doc_committed_before_saving_cas threw error");
|
350
351
|
}
|
351
352
|
item.doc().cas(res.cas);
|
352
|
-
ec = ctx
|
353
|
+
ec = ctx->hooks_.after_doc_committed(ctx, item.doc().id().key());
|
353
354
|
if (ec) {
|
354
355
|
throw client_error(*ec, "after_doc_committed threw error");
|
355
356
|
}
|
356
357
|
} catch (const client_error& e) {
|
357
358
|
error_class ec = e.ec();
|
358
|
-
if (ctx
|
359
|
+
if (ctx->expiry_overtime_mode_.load()) {
|
359
360
|
throw transaction_operation_failed(FAIL_EXPIRY, "expired during commit").no_rollback().failed_post_commit();
|
360
361
|
}
|
361
362
|
switch (ec) {
|
@@ -378,29 +379,29 @@ staged_mutation_queue::commit_doc(attempt_context_impl& ctx, staged_mutation& it
|
|
378
379
|
}
|
379
380
|
|
380
381
|
void
|
381
|
-
staged_mutation_queue::remove_doc(attempt_context_impl
|
382
|
+
staged_mutation_queue::remove_doc(attempt_context_impl* ctx, const staged_mutation& item)
|
382
383
|
{
|
383
384
|
retry_op<void>([&] {
|
384
385
|
try {
|
385
|
-
ctx
|
386
|
-
auto ec = ctx
|
386
|
+
ctx->check_expiry_during_commit_or_rollback(STAGE_REMOVE_DOC, std::optional<const std::string>(item.doc().id().key()));
|
387
|
+
auto ec = ctx->hooks_.before_doc_removed(ctx, item.doc().id().key());
|
387
388
|
if (ec) {
|
388
389
|
throw client_error(*ec, "before_doc_removed hook threw error");
|
389
390
|
}
|
390
391
|
core::operations::remove_request req{ item.doc().id() };
|
391
|
-
wrap_durable_request(req, ctx
|
392
|
+
wrap_durable_request(req, ctx->overall_.config());
|
392
393
|
auto barrier = std::make_shared<std::promise<result>>();
|
393
394
|
auto f = barrier->get_future();
|
394
|
-
ctx
|
395
|
+
ctx->cluster_ref()->execute(
|
395
396
|
req, [barrier](core::operations::remove_response resp) { barrier->set_value(result::create_from_mutation_response(resp)); });
|
396
397
|
wrap_operation_future(f);
|
397
|
-
ec = ctx
|
398
|
+
ec = ctx->hooks_.after_doc_removed_pre_retry(ctx, item.doc().id().key());
|
398
399
|
if (ec) {
|
399
400
|
throw client_error(*ec, "after_doc_removed_pre_retry threw error");
|
400
401
|
}
|
401
402
|
} catch (const client_error& e) {
|
402
403
|
error_class ec = e.ec();
|
403
|
-
if (ctx
|
404
|
+
if (ctx->expiry_overtime_mode_.load()) {
|
404
405
|
throw transaction_operation_failed(ec, e.what()).no_rollback().failed_post_commit();
|
405
406
|
}
|
406
407
|
switch (ec) {
|
@@ -104,17 +104,17 @@ class staged_mutation_queue
|
|
104
104
|
private:
|
105
105
|
std::mutex mutex_;
|
106
106
|
std::vector<staged_mutation> queue_;
|
107
|
-
void commit_doc(attempt_context_impl
|
108
|
-
void remove_doc(attempt_context_impl
|
109
|
-
void rollback_insert(attempt_context_impl
|
110
|
-
void rollback_remove_or_replace(attempt_context_impl
|
107
|
+
void commit_doc(attempt_context_impl* ctx, staged_mutation& item, bool ambiguity_resolution_mode = false, bool cas_zero_mode = false);
|
108
|
+
void remove_doc(attempt_context_impl* ctx, const staged_mutation& item);
|
109
|
+
void rollback_insert(attempt_context_impl* ctx, const staged_mutation& item);
|
110
|
+
void rollback_remove_or_replace(attempt_context_impl* ctx, const staged_mutation& item);
|
111
111
|
|
112
112
|
public:
|
113
113
|
bool empty();
|
114
114
|
void add(const staged_mutation& mutation);
|
115
115
|
void extract_to(const std::string& prefix, core::operations::mutate_in_request& req);
|
116
|
-
void commit(attempt_context_impl
|
117
|
-
void rollback(attempt_context_impl
|
116
|
+
void commit(attempt_context_impl* ctx);
|
117
|
+
void rollback(attempt_context_impl* ctx);
|
118
118
|
void iterate(std::function<void(staged_mutation&)>);
|
119
119
|
void remove_any(const core::document_id&);
|
120
120
|
|
@@ -65,13 +65,14 @@ transaction_context::has_expired_client_side()
|
|
65
65
|
auto expired_millis = std::chrono::duration_cast<std::chrono::milliseconds>(expired_nanos);
|
66
66
|
bool is_expired = expired_nanos > config_.expiration_time;
|
67
67
|
if (is_expired) {
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
68
|
+
CB_ATTEMPT_CTX_LOG_INFO(current_attempt_context_,
|
69
|
+
"has expired client side (now={}ns, start={}ns, deferred_elapsed={}ns, expired={}ns ({}ms), config={}ms)",
|
70
|
+
now.time_since_epoch().count(),
|
71
|
+
start_time_client_.time_since_epoch().count(),
|
72
|
+
deferred_elapsed_.count(),
|
73
|
+
expired_nanos.count(),
|
74
|
+
expired_millis.count(),
|
75
|
+
std::chrono::duration_cast<std::chrono::milliseconds>(config_.expiration_time).count());
|
75
76
|
}
|
76
77
|
return is_expired;
|
77
78
|
}
|
@@ -85,7 +86,8 @@ transaction_context::retry_delay()
|
|
85
86
|
// stack, so using 50 in hopes that makes jenkins happy till we do this better.
|
86
87
|
constexpr auto arbitrary_factor = 50;
|
87
88
|
auto delay = config_.expiration_time / arbitrary_factor;
|
88
|
-
|
89
|
+
CB_ATTEMPT_CTX_LOG_TRACE(
|
90
|
+
current_attempt_context_, "about to sleep for {} ms", std::chrono::duration_cast<std::chrono::milliseconds>(delay).count());
|
89
91
|
std::this_thread::sleep_for(delay);
|
90
92
|
}
|
91
93
|
|
@@ -98,7 +100,8 @@ transaction_context::new_attempt_context(async_attempt_context::VoidCallback&& c
|
|
98
100
|
try {
|
99
101
|
(*delay_)();
|
100
102
|
current_attempt_context_ = std::make_shared<attempt_context_impl>(*this);
|
101
|
-
|
103
|
+
CB_ATTEMPT_CTX_LOG_INFO(
|
104
|
+
current_attempt_context_, "starting attempt {}/{}/{}/", num_attempts(), transaction_id(), current_attempt_context_->id());
|
102
105
|
cb(nullptr);
|
103
106
|
} catch (...) {
|
104
107
|
cb(std::current_exception());
|
@@ -160,14 +163,22 @@ transaction_context::remove(const transaction_get_result& doc, async_attempt_con
|
|
160
163
|
void
|
161
164
|
transaction_context::query(const std::string& statement,
|
162
165
|
const couchbase::transactions::transaction_query_options& opts,
|
166
|
+
std::optional<std::string> query_context,
|
163
167
|
async_attempt_context::QueryCallback&& cb)
|
164
168
|
{
|
165
169
|
if (current_attempt_context_) {
|
166
|
-
return current_attempt_context_->query(statement, opts, std::move(cb));
|
170
|
+
return current_attempt_context_->query(statement, opts, query_context, std::move(cb));
|
167
171
|
}
|
168
172
|
throw(transaction_operation_failed(FAIL_OTHER, "no current attempt context"));
|
169
173
|
}
|
170
174
|
|
175
|
+
void
|
176
|
+
transaction_context::query(const std::string& statement,
|
177
|
+
const couchbase::transactions::transaction_query_options& opts,
|
178
|
+
async_attempt_context::QueryCallback&& cb)
|
179
|
+
{
|
180
|
+
query(statement, opts, {}, std::move(cb));
|
181
|
+
}
|
171
182
|
void
|
172
183
|
transaction_context::commit(async_attempt_context::VoidCallback&& cb)
|
173
184
|
{
|
@@ -206,14 +217,17 @@ transaction_context::handle_error(std::exception_ptr err, txn_complete_callback&
|
|
206
217
|
throw transaction_operation_failed(FAIL_OTHER, e.what()).cause(e.cause());
|
207
218
|
}
|
208
219
|
} catch (const transaction_operation_failed& er) {
|
209
|
-
|
220
|
+
CB_ATTEMPT_CTX_LOG_ERROR(current_attempt_context_, "got transaction_operation_failed {}", er.what());
|
210
221
|
if (er.should_rollback()) {
|
211
|
-
|
222
|
+
CB_ATTEMPT_CTX_LOG_TRACE(current_attempt_context_, "got rollback-able exception, rolling back");
|
212
223
|
try {
|
213
224
|
current_attempt_context_->rollback();
|
214
225
|
} catch (const std::exception& er_rollback) {
|
215
226
|
cleanup().add_attempt(*current_attempt_context_);
|
216
|
-
|
227
|
+
CB_ATTEMPT_CTX_LOG_TRACE(current_attempt_context_,
|
228
|
+
"got error \"{}\" while auto rolling back, throwing original error",
|
229
|
+
er_rollback.what(),
|
230
|
+
er.what());
|
217
231
|
auto final = er.get_final_exception(*this);
|
218
232
|
// if you get here, we didn't throw, yet we had an error. Fall through in
|
219
233
|
// this case. Note the current logic is such that rollback will not have a
|
@@ -222,7 +236,7 @@ transaction_context::handle_error(std::exception_ptr err, txn_complete_callback&
|
|
222
236
|
return callback(final, std::nullopt);
|
223
237
|
}
|
224
238
|
if (er.should_retry() && has_expired_client_side()) {
|
225
|
-
|
239
|
+
CB_ATTEMPT_CTX_LOG_TRACE(current_attempt_context_, "auto rollback succeeded, however we are expired so no retry");
|
226
240
|
|
227
241
|
return callback(
|
228
242
|
transaction_operation_failed(FAIL_EXPIRY, "expired in auto rollback").no_rollback().expired().get_final_exception(*this),
|
@@ -230,7 +244,7 @@ transaction_context::handle_error(std::exception_ptr err, txn_complete_callback&
|
|
230
244
|
}
|
231
245
|
}
|
232
246
|
if (er.should_retry()) {
|
233
|
-
|
247
|
+
CB_ATTEMPT_CTX_LOG_TRACE(current_attempt_context_, "got retryable exception, retrying");
|
234
248
|
cleanup().add_attempt(*current_attempt_context_);
|
235
249
|
return callback(std::nullopt, std::nullopt);
|
236
250
|
}
|
@@ -244,11 +258,11 @@ transaction_context::handle_error(std::exception_ptr err, txn_complete_callback&
|
|
244
258
|
}
|
245
259
|
return callback(final, res);
|
246
260
|
} catch (const std::exception& ex) {
|
247
|
-
|
261
|
+
CB_ATTEMPT_CTX_LOG_ERROR(current_attempt_context_, "got runtime error \"{}\"", ex.what());
|
248
262
|
try {
|
249
263
|
current_attempt_context_->rollback();
|
250
264
|
} catch (...) {
|
251
|
-
|
265
|
+
CB_ATTEMPT_CTX_LOG_ERROR(current_attempt_context_, "got error rolling back \"{}\"", ex.what());
|
252
266
|
}
|
253
267
|
cleanup().add_attempt(*current_attempt_context_);
|
254
268
|
// the assumption here is this must come from the logic, not
|
@@ -256,11 +270,11 @@ transaction_context::handle_error(std::exception_ptr err, txn_complete_callback&
|
|
256
270
|
auto op_failed = transaction_operation_failed(FAIL_OTHER, ex.what());
|
257
271
|
return callback(op_failed.get_final_exception(*this), std::nullopt);
|
258
272
|
} catch (...) {
|
259
|
-
|
273
|
+
CB_ATTEMPT_CTX_LOG_ERROR(current_attempt_context_, "got unexpected error, rolling back");
|
260
274
|
try {
|
261
275
|
current_attempt_context_->rollback();
|
262
276
|
} catch (...) {
|
263
|
-
|
277
|
+
CB_ATTEMPT_CTX_LOG_ERROR(current_attempt_context_, "got error rolling back unexpected error");
|
264
278
|
}
|
265
279
|
cleanup().add_attempt(*current_attempt_context_);
|
266
280
|
// the assumption here is this must come from the logic, not
|
@@ -15,13 +15,13 @@
|
|
15
15
|
*/
|
16
16
|
|
17
17
|
#pragma once
|
18
|
-
#include <couchbase/transactions/transaction_get_result.hxx>
|
19
|
-
|
20
18
|
#include "core/document_id.hxx"
|
21
19
|
#include "core/operations.hxx"
|
22
20
|
#include "core/utils/json.hxx"
|
23
21
|
#include "document_metadata.hxx"
|
24
22
|
#include "transaction_links.hxx"
|
23
|
+
#include <couchbase/fmt/cas.hxx>
|
24
|
+
#include <couchbase/transactions/transaction_get_result.hxx>
|
25
25
|
|
26
26
|
#include <ostream>
|
27
27
|
#include <utility>
|
@@ -227,3 +227,19 @@ class transaction_get_result : public couchbase::transactions::transaction_get_r
|
|
227
227
|
}
|
228
228
|
};
|
229
229
|
} // namespace couchbase::core::transactions
|
230
|
+
|
231
|
+
template<>
|
232
|
+
struct fmt::formatter<couchbase::core::transactions::transaction_get_result> {
|
233
|
+
public:
|
234
|
+
template<typename ParseContext>
|
235
|
+
constexpr auto parse(ParseContext& ctx)
|
236
|
+
{
|
237
|
+
return ctx.begin();
|
238
|
+
}
|
239
|
+
|
240
|
+
template<typename FormatContext>
|
241
|
+
constexpr auto format(const couchbase::core::transactions::transaction_get_result& r, FormatContext& ctx) const
|
242
|
+
{
|
243
|
+
return format_to(ctx.out(), "transaction_get_result:{{ id: {}, cas: {}, links: }}", r.id(), r.cas(), r.links());
|
244
|
+
}
|
245
|
+
};
|
@@ -16,11 +16,11 @@
|
|
16
16
|
|
17
17
|
#pragma once
|
18
18
|
|
19
|
-
#include <
|
20
|
-
|
19
|
+
#include <fmt/format.h>
|
21
20
|
#include <optional>
|
22
21
|
#include <ostream>
|
23
22
|
#include <string>
|
23
|
+
#include <tao/json/value.hpp>
|
24
24
|
|
25
25
|
namespace couchbase::core::transactions
|
26
26
|
{
|
@@ -227,3 +227,26 @@ class transaction_links
|
|
227
227
|
std::ostream&
|
228
228
|
operator<<(std::ostream& os, const transaction_links& links);
|
229
229
|
} // namespace couchbase::core::transactions
|
230
|
+
|
231
|
+
template<>
|
232
|
+
struct fmt::formatter<couchbase::core::transactions::transaction_links> {
|
233
|
+
public:
|
234
|
+
template<typename ParseContext>
|
235
|
+
constexpr auto parse(ParseContext& ctx)
|
236
|
+
{
|
237
|
+
return ctx.begin();
|
238
|
+
}
|
239
|
+
|
240
|
+
template<typename FormatContext>
|
241
|
+
constexpr auto format(const couchbase::core::transactions::transaction_links& r, FormatContext& ctx) const
|
242
|
+
{
|
243
|
+
return format_to(ctx.out(),
|
244
|
+
"transaction_links:{{ atr: {}.{}.{}.{}, txn_id: {}, attempt_id: {}, crc32_of_staging: {} }}",
|
245
|
+
r.atr_bucket_name().value_or("none"),
|
246
|
+
r.atr_scope_name().value_or("none"),
|
247
|
+
r.atr_collection_name().value_or("none"),
|
248
|
+
r.atr_id().value_or("none"),
|
249
|
+
r.staged_attempt_id().value_or("none"),
|
250
|
+
r.crc32_of_staging().value_or("none"));
|
251
|
+
}
|
252
|
+
};
|
@@ -37,7 +37,7 @@ transactions::transactions(std::shared_ptr<core::cluster> cluster, const couchba
|
|
37
37
|
, config_(config)
|
38
38
|
, cleanup_(new transactions_cleanup(cluster_, config_))
|
39
39
|
{
|
40
|
-
|
40
|
+
CB_TXN_LOG_DEBUG(
|
41
41
|
"couchbase transactions {} ({}) creating new transaction object", couchbase::core::meta::sdk_id(), couchbase::core::meta::os());
|
42
42
|
// if the config specifies custom metadata collection, lets be sure to open that bucket
|
43
43
|
// on the cluster before we start. NOTE: we actually do call get_and_open_buckets which opens all the buckets
|
@@ -59,7 +59,7 @@ transactions::transactions(std::shared_ptr<core::cluster> cluster, const couchba
|
|
59
59
|
if (err) {
|
60
60
|
auto err_msg =
|
61
61
|
fmt::format("error opening metadata_collection bucket '{}' specified in the config!", config_.metadata_collection->bucket);
|
62
|
-
|
62
|
+
CB_TXN_LOG_DEBUG(err_msg);
|
63
63
|
throw std::runtime_error(err_msg);
|
64
64
|
}
|
65
65
|
}
|
@@ -176,8 +176,8 @@ transactions::run(async_logic&& code, txn_complete_callback&& cb)
|
|
176
176
|
void
|
177
177
|
transactions::close()
|
178
178
|
{
|
179
|
-
|
179
|
+
CB_TXN_LOG_DEBUG("closing transactions");
|
180
180
|
cleanup_->close();
|
181
|
-
|
181
|
+
CB_TXN_LOG_DEBUG("transactions closed");
|
182
182
|
}
|
183
183
|
} // namespace couchbase::core::transactions
|