Add setting narinfo-cache-meta-ttl

This makes the current hard-coded 7-day `nix-cache-info` TTL
configurable, making `--offline` and `--refresh` do the right thing.
This commit is contained in:
Eelco Dolstra
2026-02-16 18:50:11 +01:00
parent 08ce8dbfba
commit 6733f2e5ce
4 changed files with 37 additions and 4 deletions

View File

@@ -86,6 +86,17 @@ struct NarInfoDiskCacheSettings : public virtual Config
would prevent trying to pull the path again and failing with a hash
mismatch if the build isn't reproducible.
)"};
Setting<unsigned int> ttlMeta{
this,
7 * 24 * 3600,
"narinfo-cache-meta-ttl",
R"(
The TTL in seconds for caching binary cache metadata (i.e.
`/nix-cache-info`). This determines how long information about a
binary cache (such as its store directory, priority, and whether it
wants mass queries) is considered valid before being refreshed.
)"};
};
class Settings : public virtual Config,

View File

@@ -63,9 +63,6 @@ struct NarInfoDiskCacheImpl : NarInfoDiskCache
/* How often to purge expired entries from the cache. */
const int purgeInterval = 24 * 3600;
/* How long to cache binary cache info (i.e. /nix-cache-info) */
const int cacheInfoTtl = 7 * 24 * 3600;
struct Cache
{
int id;
@@ -184,7 +181,7 @@ private:
{
auto i = state.caches.find(uri);
if (i == state.caches.end()) {
auto queryCache(state.queryCache.use()(uri)(time(0) - cacheInfoTtl));
auto queryCache(state.queryCache.use()(uri)(time(0) - settings.ttlMeta));
if (!queryCache.next())
return std::nullopt;
auto cache = Cache{

View File

@@ -564,12 +564,16 @@ void mainWrapped(int argc, char ** argv)
fileTransferSettings.tries = 0;
if (!fileTransferSettings.connectTimeout.overridden)
fileTransferSettings.connectTimeout = 1;
auto & ttlMeta = settings.getNarInfoDiskCacheSettings().ttlMeta;
if (!ttlMeta.overridden)
ttlMeta = std::numeric_limits<unsigned int>::max();
}
if (args.refresh) {
fetchSettings.tarballTtl = 0;
settings.getNarInfoDiskCacheSettings().ttlNegative = 0;
settings.getNarInfoDiskCacheSettings().ttlPositive = 0;
settings.getNarInfoDiskCacheSettings().ttlMeta = 0;
}
if (args.command->second->forceImpureByDefault() && !evalSettings.pureEval.overridden) {

View File

@@ -312,3 +312,24 @@ nix-store --delete "$outPath" "$docPath"
# -vvv is the level that logs during the loop
timeout 60 nix-build --no-out-link -E "$expr" --option substituters "file://$cacheDir" \
--option trusted-binary-caches "file://$cacheDir" --no-require-sigs
# Test that the narinfo-cache-meta-ttl causes nix-cache-info to be cached,
# and that --refresh overrides it.
# Populate the metadata cache by querying store info over HTTP.
_NIX_FORCE_HTTP=1 nix store info --store "file://$cacheDir"
# Remove nix-cache-info from the binary cache.
rm "$cacheDir/nix-cache-info"
# nix store info should still work because the metadata is cached
# (narinfo-cache-meta-ttl defaults to 7 days).
_NIX_FORCE_HTTP=1 nix store info --store "file://$cacheDir"
# But with --refresh, it should fail because nix-cache-info is gone
# and the cached metadata TTL is overridden to 0.
_NIX_FORCE_HTTP=1 expectStderr 1 nix store info --store "file://$cacheDir" --refresh | grepQuiet "uploading.*is not supported"
# Remove --refresh and it should work again.
_NIX_FORCE_HTTP=1 nix store info --store "file://$cacheDir"