Merge 'table_helper: observe detached setup_table() future' from Andrzej Jackowski

During shutdown, group0 may be torn down while
cache_table_info() has a detached setup_table() future
in flight. This causes raft_group_not_found to propagate
as an abandoned failed future.

Add .handle_exception() to log the failure at debug level
instead of leaving the future unobserved.

Fixes: SCYLLADB-2224

Backport to 2026.2 and 2026.1, because the test failed on 2026.1

Closes scylladb/scylladb#30093

* github.com:scylladb/scylladb:
  test: table_helper: verify detached setup failure is consumed
  table_helper: observe detached setup_table() future
This commit is contained in:
Marcin Maliszkiewicz
2026-06-01 19:32:33 +02:00
2 changed files with 19 additions and 10 deletions

View File

@@ -121,6 +121,8 @@ future<> table_helper::cache_table_info(cql3::query_processor& qp, service::migr
//FIXME: discarded future.
(void)qp.container().invoke_on(0, [&mm = mm.container(), create_cql = _create_cql] (cql3::query_processor& qp) -> future<> {
co_return co_await table_helper::setup_table(qp, mm.local(), create_cql);
}).handle_exception([keyspace = _keyspace, name = _name] (std::exception_ptr ep) {
tlogger.debug("Failed to create {}.{} table in best-effort recovery path: {}", keyspace, name, ep);
});
// We throw the bad_column_family exception because the caller

View File

@@ -35,6 +35,23 @@
BOOST_AUTO_TEST_SUITE(table_helper_test)
SEASTAR_TEST_CASE(test_best_effort_setup_table_failure_is_consumed) {
return do_with_cql_env_thread([] (cql_test_env& env) {
auto& qp = env.local_qp();
auto& mm = env.migration_manager().local();
const sstring create_cql = "CREATE TABLE IF NOT EXISTS missing_ks.t (id int PRIMARY KEY)";
const sstring insert_cql = "INSERT INTO missing_ks.t (id) VALUES (?)";
table_helper helper("missing_ks", "t", create_cql, insert_cql);
service::query_state qs(service::client_state::for_internal_calls(), empty_service_permit());
BOOST_REQUIRE_THROW(helper.cache_table_info(qp, mm, qs).get(), bad_column_family);
seastar::yield().get();
});
}
#ifdef SCYLLA_ENABLE_ERROR_INJECTION
SEASTAR_TEST_CASE(test_concurrent_invalidation) {
@@ -98,14 +115,4 @@ SEASTAR_TEST_CASE(test_concurrent_invalidation) {
#endif // SCYLLA_ENABLE_ERROR_INJECTION
#ifndef SCYLLA_ENABLE_ERROR_INJECTION
// The only test in this suite requires error injection support. Without this
// dummy case the suite would be empty, which causes boost to report
// "test tree is empty" and pytest to exit with code 5 ("no tests collected"),
// failing CI in modes (e.g. release) where error injection is disabled.
BOOST_AUTO_TEST_CASE(test_skipped_no_error_injection) {
BOOST_TEST_MESSAGE("table_helper_test requires SCYLLA_ENABLE_ERROR_INJECTION; skipping");
}
#endif
BOOST_AUTO_TEST_SUITE_END()