Skip to content

Commit

Permalink
CXXCBC-616: Columnar - report retry information when receiving a time…
Browse files Browse the repository at this point in the history
…out from the HTTP component (#681)
  • Loading branch information
DemetrisChr authored Oct 16, 2024
1 parent 79c567b commit b05f370
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 5 deletions.
11 changes: 6 additions & 5 deletions core/columnar/query_component.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,11 @@ class pending_query_operation
bootstrap_error.error_message);
self->invoke_callback({}, { maybe_convert_error_code(bootstrap_error.ec), message });
} else {
auto ec = std::get<std::error_code>(err);
self->invoke_callback(
{},
{ maybe_convert_error_code(ec), "Failed to execute the HTTP request for the query" });
auto ec = maybe_convert_error_code(std::get<std::error_code>(err));
if (ec == errc::timeout) {
return self->trigger_timeout();
}
self->invoke_callback({}, { ec, "Failed to execute the HTTP request for the query" });
}
return;
}
Expand Down Expand Up @@ -328,7 +329,7 @@ class pending_query_operation
// retryable errors should be listed.
if (err.ec == errc::timeout && retry_info_.last_error) {
if (const auto* e = retry_info_.last_error.ctx.find("errors"); e != nullptr) {
err.ctx["last_errors"] = e;
err.ctx["last_errors"] = e->get_array();
}
}
}
Expand Down
34 changes: 34 additions & 0 deletions test/test_integration_columnar_query.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -618,3 +618,37 @@ TEST_CASE("integration: closing cluster while reading columnar query rows")
auto [rows, rows_err] = buffer_rows(res);
REQUIRE(rows_err.ec == couchbase::core::columnar::client_errc::canceled);
}

TEST_CASE("integration: columnar query component timeout in raw", "[integration]")
{
test::utils::integration_test_guard integration;
if (!integration.cluster_version().is_columnar()) {
SKIP("Requires a columnar cluster");
}

couchbase::core::columnar::agent agent{ integration.io, { { integration.cluster } } };

couchbase::core::columnar::query_options options{ "SELECT SLEEP(1,10000);" };
options.timeout = std::chrono::seconds(1);

// The first request will be sent with this timeout. The server tells us to retry the server
// timeout. This means that once we eventually time out in the client, the "server timeout" will
// be reported in the error context.
options.raw = { { "timeout", couchbase::core::json_string{ "\"1ms\"" } } };

couchbase::core::columnar::query_result result;
{
auto barrier = std::make_shared<std::promise<
std::pair<couchbase::core::columnar::query_result, couchbase::core::columnar::error>>>();
auto f = barrier->get_future();
auto resp = agent.execute_query(options, [barrier](auto res, auto err) mutable {
barrier->set_value({ std::move(res), err });
});
auto [res, err] = f.get();
REQUIRE(resp.has_value());
REQUIRE(err.ec == couchbase::core::columnar::errc::timeout);
REQUIRE(err.ctx["last_errors"].get_array()[0].get_object()["code"].get_signed() == 21002);
REQUIRE(err.ctx["last_errors"].get_array()[0].get_object()["msg"].get_string() ==
"Request timed out and will be cancelled");
}
}

0 comments on commit b05f370

Please sign in to comment.