Merge pull request #3403 from hercules-ci/issue-3398-path-info-cache-ttls
pathInfoCache: Respect disk cache TTLs #3398
This commit is contained in:
commit
d048577909
|
@ -9,11 +9,11 @@ appear with Nix.
|
||||||
|
|
||||||
To find out more about the tool, usage and installation instructions, please
|
To find out more about the tool, usage and installation instructions, please
|
||||||
read the manual, which is available on the Nix website at
|
read the manual, which is available on the Nix website at
|
||||||
<http://nixos.org/nix/manual>.
|
<https://nixos.org/nix/manual>.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Take a look at the [Hacking Section](http://nixos.org/nix/manual/#chap-hacking)
|
Take a look at the [Hacking Section](https://nixos.org/nix/manual/#chap-hacking)
|
||||||
of the manual. It helps you to get started with building Nix from source.
|
of the manual. It helps you to get started with building Nix from source.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
@ -21,4 +21,4 @@ of the manual. It helps you to get started with building Nix from source.
|
||||||
Nix is released under the LGPL v2.1
|
Nix is released under the LGPL v2.1
|
||||||
|
|
||||||
This product includes software developed by the OpenSSL Project for
|
This product includes software developed by the OpenSSL Project for
|
||||||
use in the [OpenSSL Toolkit](http://www.OpenSSL.org/).
|
use in the [OpenSSL Toolkit](https://www.OpenSSL.org/).
|
||||||
|
|
|
@ -87,7 +87,7 @@ if ! [ -e $dest ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! [ -w $dest ]; then
|
if ! [ -w $dest ]; then
|
||||||
echo "$0: directory $dest exists, but is not writable by you. This could indicate that another user has already performed a single-user installation of Nix on this system. If you wish to enable multi-user support see http://nixos.org/nix/manual/#ssec-multi-user. If you wish to continue with a single-user install for $USER please run 'chown -R $USER $dest' as root." >&2
|
echo "$0: directory $dest exists, but is not writable by you. This could indicate that another user has already performed a single-user installation of Nix on this system. If you wish to enable multi-user support see https://nixos.org/nix/manual/#ssec-multi-user. If you wish to continue with a single-user install for $USER please run 'chown -R $USER $dest' as root." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ void BinaryCacheStore::writeNarInfo(ref<NarInfo> narInfo)
|
||||||
|
|
||||||
{
|
{
|
||||||
auto state_(state.lock());
|
auto state_(state.lock());
|
||||||
state_->pathInfoCache.upsert(hashPart, std::shared_ptr<NarInfo>(narInfo));
|
state_->pathInfoCache.upsert(hashPart, PathInfoCacheValue { .value = std::shared_ptr<NarInfo>(narInfo) });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (diskCache)
|
if (diskCache)
|
||||||
|
|
|
@ -622,7 +622,8 @@ uint64_t LocalStore::addValidPath(State & state,
|
||||||
|
|
||||||
{
|
{
|
||||||
auto state_(Store::state.lock());
|
auto state_(Store::state.lock());
|
||||||
state_->pathInfoCache.upsert(storePathToHash(printStorePath(info.path)), std::make_shared<ValidPathInfo>(info));
|
state_->pathInfoCache.upsert(storePathToHash(printStorePath(info.path)),
|
||||||
|
PathInfoCacheValue{ .value = std::make_shared<const ValidPathInfo>(info) });
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
|
|
|
@ -226,6 +226,14 @@ std::string Store::getUri()
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Store::PathInfoCacheValue::isKnownNow()
|
||||||
|
{
|
||||||
|
std::chrono::duration ttl = didExist()
|
||||||
|
? std::chrono::seconds(settings.ttlPositiveNarInfoCache)
|
||||||
|
: std::chrono::seconds(settings.ttlNegativeNarInfoCache);
|
||||||
|
|
||||||
|
return std::chrono::steady_clock::now() < time_point + ttl;
|
||||||
|
}
|
||||||
|
|
||||||
bool Store::isValidPath(const StorePath & storePath)
|
bool Store::isValidPath(const StorePath & storePath)
|
||||||
{
|
{
|
||||||
|
@ -234,9 +242,9 @@ bool Store::isValidPath(const StorePath & storePath)
|
||||||
{
|
{
|
||||||
auto state_(state.lock());
|
auto state_(state.lock());
|
||||||
auto res = state_->pathInfoCache.get(hashPart);
|
auto res = state_->pathInfoCache.get(hashPart);
|
||||||
if (res) {
|
if (res && res->isKnownNow()) {
|
||||||
stats.narInfoReadAverted++;
|
stats.narInfoReadAverted++;
|
||||||
return *res != 0;
|
return res->didExist();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +254,7 @@ bool Store::isValidPath(const StorePath & storePath)
|
||||||
stats.narInfoReadAverted++;
|
stats.narInfoReadAverted++;
|
||||||
auto state_(state.lock());
|
auto state_(state.lock());
|
||||||
state_->pathInfoCache.upsert(hashPart,
|
state_->pathInfoCache.upsert(hashPart,
|
||||||
res.first == NarInfoDiskCache::oInvalid ? 0 : res.second);
|
res.first == NarInfoDiskCache::oInvalid ? PathInfoCacheValue{} : PathInfoCacheValue { .value = res.second });
|
||||||
return res.first == NarInfoDiskCache::oValid;
|
return res.first == NarInfoDiskCache::oValid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,11 +309,11 @@ void Store::queryPathInfo(const StorePath & storePath,
|
||||||
|
|
||||||
{
|
{
|
||||||
auto res = state.lock()->pathInfoCache.get(hashPart);
|
auto res = state.lock()->pathInfoCache.get(hashPart);
|
||||||
if (res) {
|
if (res && res->isKnownNow()) {
|
||||||
stats.narInfoReadAverted++;
|
stats.narInfoReadAverted++;
|
||||||
if (!*res)
|
if (!res->didExist())
|
||||||
throw InvalidPath("path '%s' is not valid", printStorePath(storePath));
|
throw InvalidPath("path '%s' is not valid", printStorePath(storePath));
|
||||||
return callback(ref<const ValidPathInfo>(*res));
|
return callback(ref<const ValidPathInfo>(res->value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,7 +324,7 @@ void Store::queryPathInfo(const StorePath & storePath,
|
||||||
{
|
{
|
||||||
auto state_(state.lock());
|
auto state_(state.lock());
|
||||||
state_->pathInfoCache.upsert(hashPart,
|
state_->pathInfoCache.upsert(hashPart,
|
||||||
res.first == NarInfoDiskCache::oInvalid ? 0 : res.second);
|
res.first == NarInfoDiskCache::oInvalid ? PathInfoCacheValue{} : PathInfoCacheValue{ .value = res.second });
|
||||||
if (res.first == NarInfoDiskCache::oInvalid ||
|
if (res.first == NarInfoDiskCache::oInvalid ||
|
||||||
res.second->path != storePath)
|
res.second->path != storePath)
|
||||||
throw InvalidPath("path '%s' is not valid", printStorePath(storePath));
|
throw InvalidPath("path '%s' is not valid", printStorePath(storePath));
|
||||||
|
@ -340,7 +348,7 @@ void Store::queryPathInfo(const StorePath & storePath,
|
||||||
|
|
||||||
{
|
{
|
||||||
auto state_(state.lock());
|
auto state_(state.lock());
|
||||||
state_->pathInfoCache.upsert(hashPart, info);
|
state_->pathInfoCache.upsert(hashPart, PathInfoCacheValue { .value = info });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!info || info->path != parseStorePath(storePath)) {
|
if (!info || info->path != parseStorePath(storePath)) {
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
@ -261,10 +262,28 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
struct PathInfoCacheValue {
|
||||||
|
|
||||||
|
// Time of cache entry creation or update
|
||||||
|
std::chrono::time_point<std::chrono::steady_clock> time_point = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
// Null if missing
|
||||||
|
std::shared_ptr<const ValidPathInfo> value;
|
||||||
|
|
||||||
|
// Whether the value is valid as a cache entry. The path may not exist.
|
||||||
|
bool isKnownNow();
|
||||||
|
|
||||||
|
// Past tense, because a path can only be assumed to exists when
|
||||||
|
// isKnownNow() && didExist()
|
||||||
|
inline bool didExist() {
|
||||||
|
return value != nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct State
|
struct State
|
||||||
{
|
{
|
||||||
// FIXME: fix key
|
// FIXME: fix key
|
||||||
LRUCache<std::string, std::shared_ptr<const ValidPathInfo>> pathInfoCache;
|
LRUCache<std::string, PathInfoCacheValue> pathInfoCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
Sync<State> state;
|
Sync<State> state;
|
||||||
|
|
Loading…
Reference in a new issue