Skip to content

Check the pks version before taking the cache's stat fast path - #69

Merged
dduugg merged 2 commits into
mainfrom
cache-fast-path-checks-version
Oct 2, 2026
Merged

dduugg merged 2 commits into
mainfrom
cache-fast-path-checks-version

Conversation

@dduugg

@dduugg dduugg commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

#66 added the pks version to each cache entry's content digest, so that an upgrade would invalidate every entry. But the stat fast path from #59 returns an entry as soon as its file's mtime and length match, and never compares the digest. So for any file that hadn't changed, an entry written by another version of pks was still served. The Unreleased CHANGELOG entry "Upgrading pks invalidates cached results" didn't hold for any entry that recorded a stat.

The fast path now also requires the entry's digest to end with this version's suffix. An entry from another version falls through to the digest comparison, misses, and is rewritten. The suffix is now one constant, DIGEST_VERSION_SUFFIX, used both to build the digest and to check it.

Who this affects

Nothing released has the bug. v0.5.0 predates both #59 and #66, and its entries have no stat, so they already miss on the digest. It affects builds of main since #59, and without this fix it would affect every upgrade starting from the next release. The CHANGELOG entry already describes the fixed behavior, so it's unchanged.

To reproduce on main, run a build, change only the version, and run again on the same untouched files. Results come from the old cache entries until a file is touched or --no-cache is passed.

Test plan

  • test_entry_from_another_pks_version_is_a_miss now covers an entry carrying the file's real stat as well as one with no stat. Its old comment said a real stat would take the fast path instead, which was the bug.
  • New test_entry_from_another_pks_version_is_not_served_on_the_fast_path rewrites every cache entry as if another version had written it, with its references removed and its stat still matching the file, and checks that pks check still reports the same violations.
  • Both tests fail with the version check removed from the fast path, and pass with it.
  • cargo test (315 passed), fmt, and clippy with -Dwarnings.
  • CI passes.

c2fe84f (#66) added the pks version to each cache entry's content digest
so that an upgrade would invalidate every entry. But the stat fast path
from 96f7fb0 (#59) returns an entry as soon as its file's mtime and
length match, without comparing the digest. So for any file that hadn't
changed, an entry written by another version of pks was still served,
and the CHANGELOG's "Upgrading pks invalidates cached results" didn't
hold for any entry that recorded a stat.

The fast path now also requires the entry's digest to end with this
version's suffix. An entry from another version falls through to the
digest comparison, misses, and is rewritten. The suffix is one constant,
used both to build the digest and to check it, so the two can't drift
apart.

Neither change has shipped. v0.5.0 predates both, and its entries have
no stat, so they already miss on the digest. The bug affects builds of
main since #59, and would have affected every upgrade starting from the
next release. The CHANGELOG entry already describes the fixed behavior,
so it's unchanged.

test_entry_from_another_pks_version_is_a_miss now also covers an entry
carrying the file's real stat. Its comment said a real stat would take
the fast path instead, which was the bug. A new integration test
rewrites every entry as if another version had written it, with its
references removed and its stat still matching, and checks that the
violations are still reported. Both tests fail without the fix.
@dduugg
dduugg requested a review from a team as a code owner October 2, 2026 01:25
The fast-path comment said a matching stat meant the file "cannot have
changed in any way we care about", which the version paragraph right
below it contradicts: the file is unchanged, but its entry can still be
stale. The slow-path comment now lists an entry from another version
among the reasons for getting there.

The unit test now asserts that the file has a usable stat. On a
filesystem with whole-second mtimes it has none, and the loop's second
pass would quietly repeat the first instead of reaching the fast path.
The integration test strips the version with split_once, since an md5
hex digest has no hyphens and a prerelease version can.
@dduugg
dduugg merged commit e8dbd52 into main Oct 2, 2026
15 checks passed
@dduugg
dduugg deleted the cache-fast-path-checks-version branch October 2, 2026 16:18
@dduugg dduugg mentioned this pull request Oct 2, 2026
7 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant