#pragma once #include "ConfigProcessor.h" #include #include #include #include #include #include #include #include namespace Poco { class Logger; } namespace DB { class Context; /** Every two seconds checks configuration files for update. * If configuration is changed, then config will be reloaded by ConfigProcessor * and the reloaded config will be applied via Updater functor. * It doesn't take into account changes of --config-file, and parameters. */ class ConfigReloader { public: using Updater = std::function; /** include_from_path is usually /etc/metrika.xml (i.e. value of tag) */ ConfigReloader( const std::string & path, const std::string & include_from_path, const std::string & preprocessed_dir, zkutil::ZooKeeperNodeCache && zk_node_cache, const zkutil::EventPtr & zk_changed_event, Updater && updater, bool already_loaded); ~ConfigReloader(); /// Call this method to run the backround thread. void start(); /// Reload immediately. For SYSTEM RELOAD CONFIG query. void reload() { reloadIfNewer(/* force */ true, /* throw_on_error */ true, /* fallback_to_preprocessed */ false); } private: void run(); void reloadIfNewer(bool force, bool throw_on_error, bool fallback_to_preprocessed); struct FileWithTimestamp; struct FilesChangesTracker { std::set files; void addIfExists(const std::string & path_to_add); bool isDifferOrNewerThan(const FilesChangesTracker & rhs); }; FilesChangesTracker getNewFileList() const; private: static constexpr auto reload_interval = std::chrono::seconds(2); Poco::Logger * log = &Logger::get("ConfigReloader"); std::string path; std::string include_from_path; std::string preprocessed_dir; FilesChangesTracker files; zkutil::ZooKeeperNodeCache zk_node_cache; zkutil::EventPtr zk_changed_event = std::make_shared(); Updater updater; std::atomic quit{false}; std::thread thread; /// Locked inside reloadIfNewer. std::mutex reload_mutex; }; }