/* * Copyright (C) 2015-present ScyllaDB */ /* * SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0 */ #pragma once #include #include #include #include #include #include "utils/log.hh" #include "utils/s3/creds.hh" #include "seastarx.hh" #include #include namespace db { class extensions; class config; } namespace gms { class inet_address; } extern logging::logger startlog; class bad_configuration_error : public std::exception {}; [[nodiscard]] std::set get_seeds_from_db_config(const db::config& cfg, gms::inet_address broadcast_address, bool fail_on_lookup_error); [[nodiscard]] std::set get_disabled_features_from_db_config(const db::config& cfg, std::set disabled = {}); class service_set { public: service_set(); ~service_set(); template service_set(seastar::sharded&... args) : service_set() { (..., add(args)); } template void add(seastar::sharded& t) { add(std::any{std::addressof(t)}); } template seastar::sharded& find() const { return *std::any_cast*>(find(typeid(seastar::sharded*))); } private: void add(std::any); std::any find(const std::type_info&) const; class impl; std::unique_ptr _impl; }; /** * Very simplistic config registry. Allows hooking in a config object * to the "main" sequence. */ class configurable { public: configurable() { // We auto register. Not that like cycle is assumed to be forever // and scope should be managed elsewhere. register_configurable(*this); } virtual ~configurable() {} // Hook to add command line options and/or add main config options virtual void append_options(db::config&, boost::program_options::options_description_easy_init&) {}; // Called after command line is parsed and db/config populated. // Hooked config can for example take this opportunity to load any file(s). virtual future<> initialize(const boost::program_options::variables_map&) { return make_ready_future(); } virtual future<> initialize(const boost::program_options::variables_map& map, const db::config& cfg, db::extensions& exts) { return initialize(map); } /** * State of initiating system for optional * notification callback to objects created by * `initialize` */ enum class system_state { started, stopped, }; using notify_func = std::function(system_state)>; /** Hooks should override this to allow adding a notification function to the startup sequence. */ virtual future initialize_ex(const boost::program_options::variables_map& map, const db::config& cfg, db::extensions& exts) { return initialize(map, cfg, exts).then([] { return notify_func{}; }); } virtual future initialize_ex(const boost::program_options::variables_map& map, const db::config& cfg, db::extensions& exts, const service_set&) { return initialize_ex(map, cfg, exts); } class notify_set { public: future<> notify_all(system_state); private: friend class configurable; std::vector _listeners; }; // visible for testing static std::vector>& configurables(); static future init_all(const boost::program_options::variables_map&, const db::config&, db::extensions&, const service_set& = {}); static future init_all(const db::config&, db::extensions&, const service_set& = {}); static void append_all(db::config&, boost::program_options::options_description_easy_init&); private: static void register_configurable(configurable &); };