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