mirror of
https://github.com/facebook/sapling.git
synced 2024-10-09 16:31:02 +03:00
8a1a529fcc
Summary: Chad first noted that deserializing trees from the local store can be expensive. From the thrift side EdenFS does not have a copy of trees in memory. This means for glob files each of the trees that have not been materialized will be read from the local store. Since reading an deserializing trees from the local store can be expensive lets add an in memory cache so that some of these reads can be satisfied from here instead. Here we actually start to use the cache! Reviewed By: chadaustin Differential Revision: D27050310 fbshipit-source-id: e35db193fea0af7f387b6f44c49b5bcc2a902858
93 lines
2.8 KiB
C++
93 lines
2.8 KiB
C++
/*
|
|
* 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 <folly/logging/xlog.h>
|
|
|
|
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<const EdenConfig> config)
|
|
: state_{ConfigState{config}} {}
|
|
ReloadableConfig::ReloadableConfig(
|
|
std::shared_ptr<const EdenConfig> config,
|
|
ConfigReloadBehavior reloadBehavior)
|
|
: state_{ConfigState{config}}, reloadBehavior_{reloadBehavior} {}
|
|
|
|
ReloadableConfig::~ReloadableConfig() {}
|
|
|
|
std::shared_ptr<const EdenConfig> 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<EdenConfig>(*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
|