mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-26 11:30:36 +00:00
The feature listener callbacks are waited upon to finish in the middle of the cluster joining process. I particular -- before actually joining the cluster the format should have being selected. For that there's a .sync() method that locks the semaphore thus making sure that any update is finished and it's called right after the wait_for_gossip_to_settle() finishes. However, features are enabled inside the wait_for_gossip_to_settle() in a seastar::async() context that's also waited upon to finish. This waiting makes it possible for any feature listener to .get() any of its futures that should be resolved until gossip is settled. Said that, the format selection barrier can be moved -- instead of waiting on the semaphore, the respective part of the selection code can be .get()-ed (it all runs in async context). One thing to care about -- the remainder should continue running with the gate held. Signed-off-by: Pavel Emelyanov <xemul@scylladb.com>
80 lines
2.6 KiB
C++
80 lines
2.6 KiB
C++
/*
|
|
* Copyright (C) 2020-present ScyllaDB
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
#include <seastar/core/coroutine.hh>
|
|
#include "sstables-format-selector.hh"
|
|
#include "log.hh"
|
|
#include "replica/database.hh"
|
|
#include "gms/gossiper.hh"
|
|
#include "gms/feature_service.hh"
|
|
#include "gms/versioned_value.hh"
|
|
#include "db/system_keyspace.hh"
|
|
|
|
namespace db {
|
|
|
|
static logging::logger logger("format_selector");
|
|
static const sstring SSTABLE_FORMAT_PARAM_NAME = "sstable_format";
|
|
|
|
void feature_enabled_listener::on_enabled() {
|
|
if (!_started) {
|
|
_started = true;
|
|
_selector.maybe_select_format(_format).get();
|
|
}
|
|
}
|
|
|
|
sstables_format_selector::sstables_format_selector(gms::gossiper& g, sharded<gms::feature_service>& f, sharded<replica::database>& db)
|
|
: _gossiper(g)
|
|
, _features(f)
|
|
, _db(db)
|
|
, _md_feature_listener(*this, sstables::sstable_version_types::md)
|
|
, _me_feature_listener(*this, sstables::sstable_version_types::me)
|
|
{ }
|
|
|
|
future<> sstables_format_selector::maybe_select_format(sstables::sstable_version_types new_format) {
|
|
auto hg = _sel.hold();
|
|
auto units = co_await get_units(_sem, 1);
|
|
|
|
if (new_format > _selected_format) {
|
|
co_await db::system_keyspace::set_scylla_local_param(SSTABLE_FORMAT_PARAM_NAME, to_string(new_format));
|
|
co_await select_format(new_format);
|
|
// FIXME discarded future
|
|
(void)_gossiper.add_local_application_state(gms::application_state::SUPPORTED_FEATURES,
|
|
gms::versioned_value::supported_features(_features.local().supported_feature_set())).finally([h = std::move(hg)] {});
|
|
}
|
|
}
|
|
|
|
future<> sstables_format_selector::start() {
|
|
assert(this_shard_id() == 0);
|
|
co_await read_sstables_format();
|
|
_features.local().me_sstable.when_enabled(_me_feature_listener);
|
|
_features.local().md_sstable.when_enabled(_md_feature_listener);
|
|
}
|
|
|
|
future<> sstables_format_selector::stop() {
|
|
co_await _sel.close();
|
|
}
|
|
|
|
future<> sstables_format_selector::read_sstables_format() {
|
|
std::optional<sstring> format_opt = co_await db::system_keyspace::get_scylla_local_param(SSTABLE_FORMAT_PARAM_NAME);
|
|
if (format_opt) {
|
|
sstables::sstable_version_types format = sstables::from_string(*format_opt);
|
|
co_await select_format(format);
|
|
}
|
|
}
|
|
|
|
future<> sstables_format_selector::select_format(sstables::sstable_version_types format) {
|
|
logger.info("Selected {} sstables format", to_string(format));
|
|
_selected_format = format;
|
|
co_await _db.invoke_on_all([this] (replica::database& db) {
|
|
db.set_format(_selected_format);
|
|
});
|
|
}
|
|
|
|
} // namespace sstables
|