ClickHouse/dbms/src/Server/ConfigReloader.cpp

153 lines
3.5 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; }
2016-10-16 20:01:38 +00:00
constexpr decltype(ConfigReloader::reload_interval) ConfigReloader::reload_interval;
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
{
/// If path to users' config isn't absolute, try guess its root (current) dir.
/// At first, try to find it in dir of main config, after will use current dir.
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("ConfigReloader");
2016-01-17 13:34:36 +00:00
while (!quit)
{
std::this_thread::sleep_for(reload_interval);
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(include_from_path);
2016-01-17 13:34:36 +00:00
for (const 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 (...)
{
if (throw_on_error)
2016-01-17 13:34:36 +00:00
throw;
tryLogCurrentException(log, "Error loading config from '" + root_config_path + "' ");
return nullptr;
2016-01-17 13:34:36 +00:00
}
return config;
}
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)
{
try
{
context->setClustersConfig(config);
}
catch (...)
{
if (force_main)
throw;
tryLogCurrentException(log, "Error updating remote_servers config from '" + main_config_path + "' ");
}
}
}
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)
{
try
{
context->setUsersConfig(config);
}
catch (...)
{
if (force_users)
throw;
tryLogCurrentException(log, "Error updating users config from '" + users_config_path + "' ");
}
}
2016-01-17 13:34:36 +00:00
}
}
}