| 1 | #pragma once |
| 2 | |
| 3 | #include <thread> |
| 4 | #include <functional> |
| 5 | #include <Common/MultiVersion.h> |
| 6 | #include <Common/ThreadPool.h> |
| 7 | #include <Poco/Event.h> |
| 8 | |
| 9 | |
| 10 | namespace Poco { class Logger; namespace Util { class AbstractConfiguration; } } |
| 11 | |
| 12 | class RegionsHierarchies; |
| 13 | class RegionsNames; |
| 14 | class GeoDictionariesLoader; |
| 15 | |
| 16 | |
| 17 | namespace DB |
| 18 | { |
| 19 | |
| 20 | class Context; |
| 21 | |
| 22 | |
| 23 | /// Metrica's Dictionaries which can be used in functions. |
| 24 | |
| 25 | class EmbeddedDictionaries |
| 26 | { |
| 27 | private: |
| 28 | Poco::Logger * log; |
| 29 | Context & context; |
| 30 | |
| 31 | MultiVersion<RegionsHierarchies> regions_hierarchies; |
| 32 | MultiVersion<RegionsNames> regions_names; |
| 33 | |
| 34 | std::unique_ptr<GeoDictionariesLoader> geo_dictionaries_loader; |
| 35 | |
| 36 | /// Directories' updating periodicity (in seconds). |
| 37 | int reload_period; |
| 38 | int cur_reload_period = 1; |
| 39 | bool is_fast_start_stage = true; |
| 40 | |
| 41 | mutable std::mutex mutex; |
| 42 | |
| 43 | ThreadFromGlobalPool reloading_thread; |
| 44 | Poco::Event destroy; |
| 45 | |
| 46 | |
| 47 | void handleException(const bool throw_on_error) const; |
| 48 | |
| 49 | /** Updates directories (dictionaries) every reload_period seconds. |
| 50 | * If all dictionaries are not loaded at least once, try reload them with exponential delay (1, 2, ... reload_period). |
| 51 | * If all dictionaries are loaded, update them using constant reload_period delay. |
| 52 | */ |
| 53 | void reloadPeriodically(); |
| 54 | |
| 55 | /// Updates dictionaries. |
| 56 | bool reloadImpl(const bool throw_on_error, const bool force_reload = false); |
| 57 | |
| 58 | template <typename Dictionary> |
| 59 | using DictionaryReloader = std::function<std::unique_ptr<Dictionary>(const Poco::Util::AbstractConfiguration & config)>; |
| 60 | |
| 61 | template <typename Dictionary> |
| 62 | bool reloadDictionary( |
| 63 | MultiVersion<Dictionary> & dictionary, |
| 64 | DictionaryReloader<Dictionary> reload_dictionary, |
| 65 | const bool throw_on_error, |
| 66 | const bool force_reload); |
| 67 | |
| 68 | public: |
| 69 | /// Every reload_period seconds directories are updated inside a separate thread. |
| 70 | EmbeddedDictionaries( |
| 71 | std::unique_ptr<GeoDictionariesLoader> geo_dictionaries_loader, |
| 72 | Context & context, |
| 73 | const bool throw_on_error); |
| 74 | |
| 75 | /// Forcibly reloads all dictionaries. |
| 76 | void reload(); |
| 77 | |
| 78 | ~EmbeddedDictionaries(); |
| 79 | |
| 80 | |
| 81 | MultiVersion<RegionsHierarchies>::Version getRegionsHierarchies() const |
| 82 | { |
| 83 | return regions_hierarchies.get(); |
| 84 | } |
| 85 | |
| 86 | MultiVersion<RegionsNames>::Version getRegionsNames() const |
| 87 | { |
| 88 | return regions_names.get(); |
| 89 | } |
| 90 | }; |
| 91 | |
| 92 | } |
| 93 | |