Revert "generic_server: use async function in for_each_gently()"

This reverts commit 324b3c43c0.

It isn't safe to do asynchronous calls in `for_each_gently`, as the
connection may be disconnected while a call in callback preempts.

Fixes scylladb/scylla#21801
This commit is contained in:
Michał Jadwiszczak
2024-12-03 11:09:55 +01:00
parent 38a697d064
commit fe67efda5b
3 changed files with 7 additions and 9 deletions

View File

@@ -38,12 +38,13 @@ connection::~connection()
_server._connections_list.erase(iter);
}
future<> server::for_each_gently(noncopyable_function<future<>(connection&)> fn) {
future<> server::for_each_gently(noncopyable_function<void(connection&)> fn) {
_gentle_iterators.emplace_front(*this);
std::list<gentle_iterator>::iterator gi = _gentle_iterators.begin();
return seastar::do_until([ gi ] { return gi->iter == gi->end; },
[ gi, fn = std::move(fn) ] {
return fn(*(gi->iter++));
fn(*(gi->iter++));
return make_ready_future<>();
}
).finally([ this, gi ] { _gentle_iterators.erase(gi); });
}

View File

@@ -118,7 +118,7 @@ protected:
virtual future<> unadvertise_connection(shared_ptr<connection> conn);
future<> for_each_gently(noncopyable_function<future<>(connection&)>);
future<> for_each_gently(noncopyable_function<void(connection&)>);
};
}

View File

@@ -2044,10 +2044,9 @@ void cql_server::response::write(const cql3::prepared_metadata& m, uint8_t versi
future<utils::chunked_vector<client_data>> cql_server::get_client_data() {
utils::chunked_vector<client_data> ret;
co_await for_each_gently([&ret] (const generic_server::connection& c) -> future<> {
co_await for_each_gently([&ret] (const generic_server::connection& c) {
const connection& conn = dynamic_cast<const connection&>(c);
ret.emplace_back(conn.make_client_data());
return make_ready_future<>();
});
co_return ret;
}
@@ -2059,7 +2058,7 @@ future<> cql_server::update_connections_service_level_params() {
return make_ready_future<>();
}
return for_each_gently([this] (generic_server::connection& conn) -> future<> {
return for_each_gently([this] (generic_server::connection& conn) {
connection& cql_conn = dynamic_cast<connection&>(conn);
auto& cs = cql_conn.get_client_state();
auto& user = cs.user();
@@ -2070,13 +2069,12 @@ future<> cql_server::update_connections_service_level_params() {
cs.update_per_service_level_params(*slo);
}
}
co_return;
});
}
future<std::vector<connection_service_level_params>> cql_server::get_connections_service_level_params() {
std::vector<connection_service_level_params> sl_params;
co_await for_each_gently([&sl_params] (const generic_server::connection& conn) -> future<> {
co_await for_each_gently([&sl_params] (const generic_server::connection& conn) {
auto& cql_conn = dynamic_cast<const connection&>(conn);
auto& client_state = cql_conn.get_client_state();
auto& user = client_state.user();
@@ -2085,7 +2083,6 @@ future<std::vector<connection_service_level_params>> cql_server::get_connections
: "UNAUTHENTICATED";
sl_params.emplace_back(std::move(role_name), client_state.get_timeout_config(), client_state.get_workload_type());
co_return;
});
co_return sl_params;
}