1 | #pragma once |
2 | |
3 | #include "ConfigProcessor.h" |
4 | #include <Common/ThreadPool.h> |
5 | #include <Common/ZooKeeper/Common.h> |
6 | #include <Common/ZooKeeper/ZooKeeperNodeCache.h> |
7 | #include <time.h> |
8 | #include <string> |
9 | #include <thread> |
10 | #include <mutex> |
11 | #include <condition_variable> |
12 | #include <list> |
13 | |
14 | |
15 | namespace Poco { class Logger; } |
16 | |
17 | namespace DB |
18 | { |
19 | |
20 | class Context; |
21 | |
22 | /** Every two seconds checks configuration files for update. |
23 | * If configuration is changed, then config will be reloaded by ConfigProcessor |
24 | * and the reloaded config will be applied via Updater functor. |
25 | * It doesn't take into account changes of --config-file, <users_config> and <include_from> parameters. |
26 | */ |
27 | class ConfigReloader |
28 | { |
29 | public: |
30 | using Updater = std::function<void(ConfigurationPtr)>; |
31 | |
32 | /** include_from_path is usually /etc/metrika.xml (i.e. value of <include_from> tag) |
33 | */ |
34 | ConfigReloader( |
35 | const std::string & path, |
36 | const std::string & include_from_path, |
37 | const std::string & preprocessed_dir, |
38 | zkutil::ZooKeeperNodeCache && zk_node_cache, |
39 | const zkutil::EventPtr & zk_changed_event, |
40 | Updater && updater, |
41 | bool already_loaded); |
42 | |
43 | ~ConfigReloader(); |
44 | |
45 | /// Call this method to run the backround thread. |
46 | void start(); |
47 | |
48 | /// Reload immediately. For SYSTEM RELOAD CONFIG query. |
49 | void reload() { reloadIfNewer(/* force */ true, /* throw_on_error */ true, /* fallback_to_preprocessed */ false); } |
50 | |
51 | private: |
52 | void run(); |
53 | |
54 | void reloadIfNewer(bool force, bool throw_on_error, bool fallback_to_preprocessed); |
55 | |
56 | struct FileWithTimestamp; |
57 | |
58 | struct FilesChangesTracker |
59 | { |
60 | std::set<FileWithTimestamp> files; |
61 | |
62 | void addIfExists(const std::string & path_to_add); |
63 | bool isDifferOrNewerThan(const FilesChangesTracker & rhs); |
64 | }; |
65 | |
66 | FilesChangesTracker getNewFileList() const; |
67 | |
68 | private: |
69 | |
70 | static constexpr auto reload_interval = std::chrono::seconds(2); |
71 | |
72 | Poco::Logger * log = &Logger::get("ConfigReloader" ); |
73 | |
74 | std::string path; |
75 | std::string include_from_path; |
76 | std::string preprocessed_dir; |
77 | FilesChangesTracker files; |
78 | zkutil::ZooKeeperNodeCache zk_node_cache; |
79 | bool need_reload_from_zk = false; |
80 | zkutil::EventPtr zk_changed_event = std::make_shared<Poco::Event>(); |
81 | |
82 | Updater updater; |
83 | |
84 | std::atomic<bool> quit{false}; |
85 | ThreadFromGlobalPool thread; |
86 | |
87 | /// Locked inside reloadIfNewer. |
88 | std::mutex reload_mutex; |
89 | }; |
90 | |
91 | } |
92 | |