2016-10-11 14:37:27 +00:00
|
|
|
#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;
|
|
|
|
|
|
|
|
|
2016-10-14 15:06:46 +00:00
|
|
|
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
|
|
|
{
|
2016-10-14 15:06:46 +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.
|
2016-10-10 08:44:52 +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();
|
2016-10-10 08:44:52 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2016-10-10 08:44:52 +00:00
|
|
|
/// Setup users on server init
|
|
|
|
reloadIfNewer(false, true);
|
|
|
|
|
2016-10-11 14:37:27 +00:00
|
|
|
thread = std::thread(&ConfigReloader::run, this);
|
2016-01-17 13:34:36 +00:00
|
|
|
}
|
|
|
|
|
2016-10-11 14:37:27 +00:00
|
|
|
ConfigReloader::~ConfigReloader()
|
2016-01-17 13:34:36 +00:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2016-10-11 14:37:27 +00:00
|
|
|
LOG_DEBUG(log, "ConfigReloader::~ConfigReloader()");
|
2016-01-17 13:34:36 +00:00
|
|
|
quit = true;
|
|
|
|
thread.join();
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
2016-10-11 14:37:27 +00:00
|
|
|
tryLogCurrentException("~ConfigReloader");
|
2016-01-17 13:34:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-10-11 14:37:27 +00:00
|
|
|
void ConfigReloader::run()
|
2016-01-17 13:34:36 +00:00
|
|
|
{
|
2016-10-14 15:06:46 +00:00
|
|
|
setThreadName("ConfigReloader");
|
2016-01-17 13:34:36 +00:00
|
|
|
|
|
|
|
while (!quit)
|
|
|
|
{
|
2016-10-14 15:06:46 +00:00
|
|
|
std::this_thread::sleep_for(reload_interval);
|
2016-10-10 08:44:52 +00:00
|
|
|
reloadIfNewer(false, false);
|
2016-01-17 13:34:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-10-11 14:37:27 +00:00
|
|
|
ConfigReloader::FilesChangesTracker ConfigReloader::getFileListFor(const std::string & root_config_path)
|
2016-01-17 13:34:36 +00:00
|
|
|
{
|
2016-10-10 08:44:52 +00:00
|
|
|
FilesChangesTracker file_list;
|
2016-01-17 13:34:36 +00:00
|
|
|
|
2016-10-10 08:44:52 +00:00
|
|
|
file_list.addIfExists(root_config_path);
|
2016-10-14 15:06:46 +00:00
|
|
|
file_list.addIfExists(include_from_path);
|
2016-01-17 13:34:36 +00:00
|
|
|
|
2016-10-14 15:06:46 +00:00
|
|
|
for (const auto & path : ConfigProcessor::getConfigMergeFiles(root_config_path))
|
2016-10-10 08:44:52 +00:00
|
|
|
file_list.addIfExists(path);
|
|
|
|
|
|
|
|
return file_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-10-11 14:37:27 +00:00
|
|
|
ConfigurationPtr ConfigReloader::loadConfigFor(const std::string & root_config_path, bool throw_on_error)
|
2016-10-10 08:44:52 +00:00
|
|
|
{
|
2016-01-17 13:34:36 +00:00
|
|
|
ConfigurationPtr config;
|
|
|
|
|
2016-10-10 08:44:52 +00:00
|
|
|
LOG_DEBUG(log, "Loading config '" << root_config_path << "'");
|
|
|
|
|
2016-01-17 13:34:36 +00:00
|
|
|
try
|
|
|
|
{
|
2016-10-10 08:44:52 +00:00
|
|
|
config = ConfigProcessor().loadConfig(root_config_path);
|
2016-01-17 13:34:36 +00:00
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
2016-10-10 08:44:52 +00:00
|
|
|
if (throw_on_error)
|
2016-01-17 13:34:36 +00:00
|
|
|
throw;
|
|
|
|
|
2016-10-14 15:06:46 +00:00
|
|
|
tryLogCurrentException(log, "Error loading config from '" + root_config_path + "' ");
|
2016-10-10 08:44:52 +00:00
|
|
|
return nullptr;
|
2016-01-17 13:34:36 +00:00
|
|
|
}
|
|
|
|
|
2016-10-10 08:44:52 +00:00
|
|
|
return config;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-10-11 14:37:27 +00:00
|
|
|
void ConfigReloader::reloadIfNewer(bool force_main, bool force_users)
|
2016-10-10 08:44:52 +00:00
|
|
|
{
|
|
|
|
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)
|
2016-10-14 15:06:46 +00:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
context->setClustersConfig(config);
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
|
|
|
if (force_main)
|
|
|
|
throw;
|
|
|
|
tryLogCurrentException(log, "Error updating remote_servers config from '" + main_config_path + "' ");
|
|
|
|
}
|
|
|
|
}
|
2016-10-10 08:44:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
2016-10-14 15:06:46 +00:00
|
|
|
{
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|