Skip to content

perf(hasher): reduce redundant file hashing work - #1257

Open
djordjem88 wants to merge 3 commits into
microsoft:mainfrom
djordjem88:user/djmaks/lage-file-hashing-work
Open

djordjem88 wants to merge 3 commits into
microsoft:mainfrom
djordjem88:user/djmaks/lage-file-hashing-work

Conversation

@djordjem88

Copy link
Copy Markdown
Contributor

Summary

Requested reviewers: Nemanja Tesic (@nemanjatesic) and Elizabeth Craig (@ecraig12345).

Skip native stat/hash calls for empty inputs and skip native hashing when every requested file is already cached. Reuse pre-hash metadata instead of calling statSync again after hashing, so an edit during hashing is not paired with newer metadata and incorrectly reused on the next lookup.

Stale entries are evicted before refresh. A valid hash without matching pre-hash metadata is returned without caching it.

Part of the broader Lage performance effort explored in #1238. This change is self-contained and based on current main; it does not depend on the other performance PRs.

Behavior change for review

This is not exclusively a performance change. A null native batch result now throws Failed to hash files instead of being treated as an empty result. A nullish individual native hash now throws instead of being converted to an empty string. These explicit failures were deliberately retained for reviewer discussion; previous incidental filesystem failures could already throw, but these native-result cases broaden the error behavior.

Validation

  • Synced with main at cf155216 without conflicts; the hasher implementation and tests are unchanged by the sync.
  • Final independent branch: all 26 hasher tests passed across three suites.
  • Twelve added file-hasher cases cover empty inputs, cache reuse, changed metadata, edits during hashing, missing metadata, native failures, normalized result paths, and recovery after failed refreshes.
  • Full local CI passed during implementation (20 successful targets, 101 cached/skipped, zero failures). This is not a claim about GitHub PR CI.
  • Includes a Beachball patch note. No end-to-end speedup claim.

Djordje Maksimovic and others added 3 commits November 6, 2026 14:05
Skip empty native calls and reuse pre-hash metadata. Invalidate stale entries and surface native hashing failures explicitly, with regression coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7b26a45b-25aa-45e3-95b4-f9a1b55dcb58
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7b26a45b-25aa-45e3-95b4-f9a1b55dcb58
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7b26a45b-25aa-45e3-95b4-f9a1b55dcb58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Hash failures are logged without settling worker requests, leaving cacheable targets waiting indefinitely and hanging the build.

3 open issues
What changed in this PR

Reduces redundant work in Lage’s file-hashing layer and improves cache consistency when files change during hashing. This is a self-contained optimization, separate from the broader experimental cache-hit work.

Changes:

  • Skips native calls for empty inputs and native hashing for fully cached inputs.
  • Reuses pre-hash metadata, invalidates stale entries, and makes null native results explicit failures.
  • Adds focused regression tests and a patch release note.
File Description
packages/​hasher/​src/​FileHasher.ts Adds fast paths, metadata reuse, cache invalidation, and explicit native-result errors.
packages/​hasher/​src/​__tests__/​FileHasher.test.ts Covers cache reuse, metadata changes, hashing races, normalized paths, and failure recovery.
change/​change-3d55df9e-d087-4b46-9a27-4aa36592561c.json Records the hasher improvements and changed failure behavior as a patch release.

Review effort: Max

Comment on lines +123 to +124
if (!updatedHashes) {
throw new Error("Failed to hash files");
Comment on lines +129 to +130
// Evict the native result's normalized key; input paths may use a different form.
delete this.#store[file];
if (hash == null) {
// Evict the native result's normalized key; input paths may use a different form.
delete this.#store[file];
throw new Error(`Failed to hash file "${file}"`);

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants