ClickHouse/dbms/src/Server/ConfigReloader.cpp

180 lines
4.4 KiB
C++
Raw Normal View History

#include "ConfigReloader.h"
2016-01-17 13:34:36 +00:00
#include <Poco/Util/Application.h>
#include <Poco/File.h>
#include <common/logger_useful.h>
#include <DB/Interpreters/Context.h>
#include <DB/Common/setThreadName.h>
#include <DB/Common/ConfigProcessor.h>
namespace DB
{
namespace ErrorCodes { extern const int FILE_DOESNT_EXIST; }
ConfigReloader::ConfigReloader(const std::string & main_config_path_, const std::string & users_config_path_, const std::string & include_from_path_, Context * context_)
: main_config_path(main_config_path_), users_config_path(users_config_path_), include_from_path(include_from_path_), context(context_)
2016-01-17 13:34:36 +00:00
{
/// Assume that paths derived from --config-file, <users_config> and <include_from> are not changed
2016-01-17 13:34:36 +00:00
/// Если путь к конфигу не абсолютный, угадаем, относительно чего он задан.
/// Сначала поищем его рядом с основным конфигом, потом - в текущей директории.
if (users_config_path.empty() || users_config_path[0] != '/')
2016-01-17 13:34:36 +00:00
{
std::string config_dir = Poco::Path(main_config_path).parent().toString();
if (Poco::File(config_dir + users_config_path).exists())
users_config_path = config_dir + users_config_path;
2016-01-17 13:34:36 +00:00
}
/// Setup users on server init
reloadIfNewer(false, true);
thread = std::thread(&ConfigReloader::run, this);
2016-01-17 13:34:36 +00:00
}
ConfigReloader::~ConfigReloader()
2016-01-17 13:34:36 +00:00
{
try
{
LOG_DEBUG(log, "ConfigReloader::~ConfigReloader()");
2016-01-17 13:34:36 +00:00
quit = true;
thread.join();
}
catch (...)
{
tryLogCurrentException("~ConfigReloader");
2016-01-17 13:34:36 +00:00
}
}
void ConfigReloader::run()
2016-01-17 13:34:36 +00:00
{
setThreadName("UserConfReload");
while (!quit)
{
std::this_thread::sleep_for(std::chrono::seconds(2));
reloadIfNewer(false, false);
2016-01-17 13:34:36 +00:00
}
}
ConfigReloader::FilesChangesTracker ConfigReloader::getFileListFor(const std::string & root_config_path)
2016-01-17 13:34:36 +00:00
{
FilesChangesTracker file_list;
2016-01-17 13:34:36 +00:00
file_list.addIfExists(root_config_path);
file_list.addIfExists(this->include_from_path);
2016-01-17 13:34:36 +00:00
for (auto & path : ConfigProcessor::getConfigMergeFiles(root_config_path))
file_list.addIfExists(path);
return file_list;
}
ConfigurationPtr ConfigReloader::loadConfigFor(const std::string & root_config_path, bool throw_on_error)
{
2016-01-17 13:34:36 +00:00
ConfigurationPtr config;
LOG_DEBUG(log, "Loading config '" << root_config_path << "'");
2016-01-17 13:34:36 +00:00
try
{
config = ConfigProcessor().loadConfig(root_config_path);
2016-01-17 13:34:36 +00:00
}
catch (Poco::Exception & e)
{
if (throw_on_error)
2016-01-17 13:34:36 +00:00
throw;
LOG_ERROR(log, "Error loading config from '" << root_config_path << "' : " << e.what() << ": " << e.displayText());
return nullptr;
2016-01-17 13:34:36 +00:00
}
catch (...)
{
if (throw_on_error)
2016-01-17 13:34:36 +00:00
throw;
LOG_ERROR(log, "Error loading config from '" << root_config_path << "'.");
return nullptr;
2016-01-17 13:34:36 +00:00
}
return config;
}
bool ConfigReloader::applyConfigFor(bool for_main, ConfigurationPtr config, bool throw_on_error)
{
auto & root_config_path = (for_main) ? main_config_path : users_config_path;
2016-01-17 13:34:36 +00:00
try
{
if (for_main)
{
context->setClustersConfig(config);
}
else
{
context->setUsersConfig(config);
}
2016-01-17 13:34:36 +00:00
}
catch (Exception & e)
{
if (throw_on_error)
2016-01-17 13:34:36 +00:00
throw;
LOG_ERROR(log, "Error updating config from '" << root_config_path << "': " << e.what() << ": " << e.displayText() << "\n" << e.getStackTrace().toString());
return false;
2016-01-17 13:34:36 +00:00
}
catch (Poco::Exception & e)
{
if (throw_on_error)
2016-01-17 13:34:36 +00:00
throw;
LOG_ERROR(log, "Error updating config from '" << root_config_path << "': " << e.what() << ": " << e.displayText());
return false;
2016-01-17 13:34:36 +00:00
}
catch (...)
{
if (throw_on_error)
2016-01-17 13:34:36 +00:00
throw;
LOG_ERROR(log, "Error updating config from '" << root_config_path << "'.");
return false;
}
return true;
}
void ConfigReloader::reloadIfNewer(bool force_main, bool force_users)
{
FilesChangesTracker main_config_files = getFileListFor(main_config_path);
if (force_main || main_config_files.isDifferOrNewerThan(last_main_config_files))
{
last_main_config_files = std::move(main_config_files);
ConfigurationPtr config = loadConfigFor(main_config_path, force_main);
if (config)
applyConfigFor(true, config, force_main);
}
FilesChangesTracker users_config_files = getFileListFor(users_config_path);
if (force_users || users_config_files.isDifferOrNewerThan(last_users_config_files))
{
last_users_config_files = std::move(users_config_files);
ConfigurationPtr config = loadConfigFor(users_config_path, force_users);
if (config)
applyConfigFor(false, config, force_users);
2016-01-17 13:34:36 +00:00
}
}
}