/* * Copyright (c) Facebook, Inc. and its affiliates. * * This software may be used and distributed according to the terms of the * GNU General Public License version 2. */ #include "eden/fs/config/ReloadableConfig.h" #include "eden/fs/config/EdenConfig.h" #include "eden/fs/utils/Bug.h" #include "eden/fs/utils/EnumValue.h" #include namespace { /// Throttle change checks to a maximum of one per /// kEdenConfigMinimumPollDuration. constexpr std::chrono::seconds kEdenConfigMinimumPollDuration{5}; } // namespace namespace facebook { namespace eden { ReloadableConfig::ReloadableConfig(std::shared_ptr config) : state_{ConfigState{config}} {} ReloadableConfig::ReloadableConfig( std::shared_ptr config, ConfigReloadBehavior reloadBehavior) : state_{ConfigState{config}}, reloadBehavior_{reloadBehavior} {} ReloadableConfig::~ReloadableConfig() {} std::shared_ptr ReloadableConfig::getEdenConfig( ConfigReloadBehavior reload) { auto now = std::chrono::steady_clock::now(); // TODO: Update this monitoring code to use FileChangeMonitor. bool shouldReload; if (reloadBehavior_.has_value()) { reload = reloadBehavior_.value(); } switch (reload) { case ConfigReloadBehavior::NoReload: shouldReload = false; break; case ConfigReloadBehavior::ForceReload: shouldReload = true; break; case ConfigReloadBehavior::AutoReload: { auto lastCheck = std::chrono::steady_clock::time_point{ std::chrono::steady_clock::duration{ lastCheck_.load(std::memory_order_acquire)}}; shouldReload = now - lastCheck >= kEdenConfigMinimumPollDuration; break; } default: EDEN_BUG() << "Unexpected reload flag: " << enumValue(reload); } if (!shouldReload) { return state_.rlock()->config; } auto state = state_.wlock(); // Throttle the updates when using ConfigReloadBehavior::AutoReload lastCheck_.store(now.time_since_epoch().count(), std::memory_order_release); auto& config = state->config; auto userConfigChanged = config->hasUserConfigFileChanged(); auto systemConfigChanged = config->hasSystemConfigFileChanged(); if (userConfigChanged || systemConfigChanged) { auto newConfig = std::make_shared(*config); if (userConfigChanged) { XLOG(DBG3) << "Reloading " << config->getUserConfigPath() << " because " << userConfigChanged.str(); newConfig->loadUserConfig(); } if (systemConfigChanged) { XLOG(DBG3) << "Reloading " << config->getSystemConfigPath() << " because " << systemConfigChanged.str(); newConfig->loadSystemConfig(); } state->config = std::move(newConfig); } return state->config; } } // namespace eden } // namespace facebook