2015-01-21 11:39:48 +00:00
|
|
|
#include <DB/Interpreters/Dictionaries.h>
|
|
|
|
#include <DB/Dictionaries/DictionaryFactory.h>
|
2015-01-26 16:53:44 +00:00
|
|
|
#include <DB/Dictionaries/config_ptr_t.h>
|
2015-01-21 11:39:48 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2015-01-26 15:27:51 +00:00
|
|
|
void Dictionaries::reloadExternals()
|
2015-01-21 11:39:48 +00:00
|
|
|
{
|
2015-01-26 15:27:51 +00:00
|
|
|
const std::lock_guard<std::mutex> lock{externals_mutex};
|
|
|
|
|
2015-01-21 11:39:48 +00:00
|
|
|
const auto config_path = Poco::Util::Application::instance().config().getString("dictionaries_config");
|
2015-01-22 14:32:38 +00:00
|
|
|
if (config_path.empty())
|
|
|
|
return;
|
|
|
|
|
2015-01-26 15:27:51 +00:00
|
|
|
const auto last_modified = Poco::File{config_path}.getLastModified();
|
|
|
|
if (last_modified > dictionaries_last_modified)
|
|
|
|
{
|
|
|
|
dictionaries_last_modified = last_modified;
|
2015-01-21 11:39:48 +00:00
|
|
|
|
2015-01-26 15:27:51 +00:00
|
|
|
const config_ptr_t<Poco::Util::XMLConfiguration> config{new Poco::Util::XMLConfiguration{config_path}};
|
2015-01-21 11:39:48 +00:00
|
|
|
|
2015-01-26 15:27:51 +00:00
|
|
|
/// get all dictionaries' definitions
|
|
|
|
Poco::Util::AbstractConfiguration::Keys keys;
|
|
|
|
config->keys(keys);
|
|
|
|
|
|
|
|
/// for each dictionary defined in xml config
|
|
|
|
for (const auto & key : keys)
|
2015-01-21 11:39:48 +00:00
|
|
|
{
|
2015-01-30 13:43:16 +00:00
|
|
|
try
|
2015-01-26 15:27:51 +00:00
|
|
|
{
|
2015-01-30 13:43:16 +00:00
|
|
|
if (0 != strncmp(key.data(), "dictionary", strlen("dictionary")))
|
|
|
|
{
|
|
|
|
LOG_WARNING(log, "unknown node in dictionaries file: '" + key + "', 'dictionary'");
|
|
|
|
continue;
|
|
|
|
}
|
2015-01-21 11:39:48 +00:00
|
|
|
|
2015-01-30 13:43:16 +00:00
|
|
|
const auto & prefix = key + '.';
|
2015-01-21 11:39:48 +00:00
|
|
|
|
2015-01-30 13:43:16 +00:00
|
|
|
const auto & name = config->getString(prefix + "name");
|
|
|
|
if (name.empty())
|
|
|
|
{
|
|
|
|
LOG_WARNING(log, "dictionary name cannot be empty");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto & lifetime_key = prefix + "lifetime";
|
|
|
|
const auto & lifetime_min_key = lifetime_key + ".min";
|
|
|
|
const auto has_min = config->has(lifetime_min_key);
|
|
|
|
const auto min_update_time = has_min ? config->getInt(lifetime_min_key) : config->getInt(lifetime_key);
|
|
|
|
const auto max_update_time = has_min ? config->getInt(lifetime_key + ".max") : min_update_time;
|
|
|
|
|
|
|
|
std::cout << "min_update_time = " << min_update_time << " max_update_time = " << max_update_time << std::endl;
|
2015-01-21 11:39:48 +00:00
|
|
|
|
2015-01-26 15:27:51 +00:00
|
|
|
auto it = external_dictionaries.find(name);
|
|
|
|
if (it == std::end(external_dictionaries))
|
|
|
|
{
|
2015-01-29 15:47:21 +00:00
|
|
|
/// such a dictionary is not present at the moment
|
|
|
|
auto dict_ptr = DictionaryFactory::instance().create(name, *config, prefix, context);
|
2015-01-26 15:27:51 +00:00
|
|
|
external_dictionaries.emplace(name, std::make_shared<MultiVersion<IDictionary>>(dict_ptr.release()));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-01-29 15:47:21 +00:00
|
|
|
/// dictionary exists, it may be desirable to reload it
|
2015-01-26 15:27:51 +00:00
|
|
|
auto & current = it->second->get();
|
2015-01-29 15:47:21 +00:00
|
|
|
if (current->isCached())
|
|
|
|
const_cast<IDictionary *>(current.get())->reload();
|
|
|
|
else
|
2015-01-26 15:27:51 +00:00
|
|
|
{
|
|
|
|
/// @todo check that timeout has passed
|
2015-01-29 15:47:21 +00:00
|
|
|
auto dict_ptr = DictionaryFactory::instance().create(name, *config, prefix, context);
|
2015-01-26 15:27:51 +00:00
|
|
|
it->second->set(dict_ptr.release());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-01-30 13:43:16 +00:00
|
|
|
catch (...)
|
2015-01-26 15:27:51 +00:00
|
|
|
{
|
|
|
|
handleException();
|
|
|
|
}
|
2015-01-21 11:39:48 +00:00
|
|
|
}
|
2015-01-26 15:27:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (auto & dictionary : external_dictionaries)
|
2015-01-21 11:39:48 +00:00
|
|
|
{
|
2015-01-26 15:27:51 +00:00
|
|
|
try
|
|
|
|
{
|
2015-01-29 15:47:21 +00:00
|
|
|
auto current = dictionary.second->get();
|
|
|
|
if (current->isCached())
|
2015-01-26 15:27:51 +00:00
|
|
|
{
|
2015-01-29 15:47:21 +00:00
|
|
|
const_cast<IDictionary *>(current.get())->reload();
|
2015-01-26 15:27:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-01-29 15:47:21 +00:00
|
|
|
/// @todo check that timeout has passed and load new version
|
|
|
|
if (!current->getSource()->isModified())
|
|
|
|
continue;
|
|
|
|
|
2015-01-30 13:43:16 +00:00
|
|
|
auto new_version = current->clone();
|
|
|
|
dictionary.second->set(new_version.release());
|
2015-01-26 15:27:51 +00:00
|
|
|
}
|
|
|
|
}
|
2015-01-30 13:43:16 +00:00
|
|
|
catch (...)
|
2015-01-26 15:27:51 +00:00
|
|
|
{
|
|
|
|
handleException();
|
|
|
|
}
|
2015-01-21 11:39:48 +00:00
|
|
|
}
|
|
|
|
}
|
2015-01-26 15:27:51 +00:00
|
|
|
}
|
2015-01-21 11:39:48 +00:00
|
|
|
|
|
|
|
}
|