nix icon indicating copy to clipboard operation
nix copied to clipboard

`fetchGit` with a fixed rev and no ref repeatedly hits the network

Open marienz opened this issue 1 year ago • 2 comments

Repeatedly fetching the same fixed rev using fetchGit hits the network each time once the cache is older than tarball-ttl (not just once to refresh the cache).

Steps To Reproduce

# Populate the cache:
nix eval --debug --expr 'builtins.fetchGit { url = "https://github.com/NixOS/nix.git"; rev = "2c42e7b8d9ea32e59c01334852599b548b214d31"; }'
# Wait 1 minute.
# Re-fetch the same rev (with tarball-ttl decreased to avoid having to wait an hour in the previous step). Observe this hits the network.
nix eval --option tarball-ttl 60  --debug --expr 'builtins.fetchGit { url = "https://github.com/NixOS/nix.git"; rev = "2c42e7b8d9ea32e59c01334852599b548b214d31"; }'
# Re-fetch the same rev again (within tarball-ttl from the second attempt). Observe this hits the network again.
nix eval --option tarball-ttl 60  --debug --expr 'builtins.fetchGit { url = "https://github.com/NixOS/nix.git"; rev = "2c42e7b8d9ea32e59c01334852599b548b214d31"; }'

This hits the network, seemingly to resolve the HEAD ref: the network hit occcurs between

resolved HEAD rev '2c42e7b8d9ea32e59c01334852599b548b214d31' for repo '/home/marienz/.cache/nix/gitv3/0rxngja0chlk8xlxh0qbhc9q5dznnlgkh32slphfhgyrb6rnbkqp'
resolved HEAD ref 'refs/heads/master' for repo 'https://github.com/NixOS/nix.git'

(I'm noticing this hits the network because it takes about 800ms instead of about 10ms, but I'm in Australia: if you're closer to Github the problem may be less noticeable.)

Expected behavior

If the requested rev is already cached, the cache is used without hitting the network. Or if it is necessary to verify the requested rev is obtainable from a particular ref (to avoid #7120): this verification only occurs once every tarball-ttl, not on every attempt once the cache is older than tarball-ttl.

nix-env --version output nix-env (Nix) 2.22.1

Additional context

Nix 2.18.2 does not have this problem.

It looks like the network hit occurs from the getDefaultRef() call in git.cc: passing in some ref makes me hit the cache again. (Any value for ref seems to work, although I'm guessing that's only because of #7120.) From there we end up in readHeadCached() which hits the network if the cached HEAD file is older than tarball-ttl, seemingly without updating that file.

#6830 is somewhat related: that issue points out that caching revs is undesirable if Nix is fetching by ref (without a rev specified). If a rev is specified, caching seems very desirable.

Priorities

Add :+1: to issues you find important.

marienz avatar May 25 '24 02:05 marienz

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/2024-05-29-nix-team-meeting-minutes-148/46195/1

nixos-discourse avatar May 29 '24 21:05 nixos-discourse

Same here. Can confirm that this behavior is observed on 2.23, but not on 2.18.

mode89 avatar Jun 27 '24 01:06 mode89

Using @marienz's test script, can confirm the regression happened between Nix 2.19.7 and 2.20.9.

VictorEngmarkHexagon avatar Mar 21 '25 12:03 VictorEngmarkHexagon