EmbeddedDictionaries::EmbeddedDictionaries(
    std::unique_ptr<IGeoDictionariesLoader> geo_dictionaries_loader_,
    Context & context_,
    const bool throw_on_error)
    : log(&Logger::get("EmbeddedDictionaries"))
    , context(context_)
    , geo_dictionaries_loader(std::move(geo_dictionaries_loader_))
    , reload_period(context_.getConfigRef().getInt("builtin_dictionaries_reload_interval", 3600))
{
    reloadImpl(throw_on_error);
    reloading_thread = std::thread([this] { reloadPeriodically(); });
}
ExternalDictionaries::ExternalDictionaries(Context & context, const bool throw_on_error)
    : context(context), log(&Logger::get("ExternalDictionaries"))
{
    {
        /** During synchronous loading of external dictionaries at moment of query execution,
            *  we should not use per query memory limit.
            */
        TemporarilyDisableMemoryTracker temporarily_disable_memory_tracker;

        reloadImpl(throw_on_error);
    }

    reloading_thread = std::thread{&ExternalDictionaries::reloadPeriodically, this};
}
void EmbeddedDictionaries::reloadPeriodically()
{
    setThreadName("DictReload");

    while (true)
    {
        if (destroy.tryWait(cur_reload_period * 1000))
            return;

        if (reloadImpl(false))
        {
            /// Success
            cur_reload_period = reload_period;
            is_fast_start_stage = false;
        }

        if (is_fast_start_stage)
        {
            cur_reload_period = std::min(reload_period, 2 * cur_reload_period); /// exponentially increase delay
            is_fast_start_stage = cur_reload_period < reload_period; /// leave fast start state
        }
    }
}
void EmbeddedDictionaries::reload()
{
    if (!reloadImpl(true, true))
        throw Exception("Some embedded dictionaries were not successfully reloaded", ErrorCodes::UNFINISHED);
}