-
Notifications
You must be signed in to change notification settings - Fork 6
fix(pnp): cache the manifest by its own path #69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(pnp): cache the manifest by its own path #69
Conversation
src/lib.rs
Outdated
| self.pnp_manifest_path_cache.entry(cached_path.to_path_buf()).or_insert_with(|| { | ||
| let manifest_path = | ||
| pnp::find_closest_pnp_manifest_path(cached_path.to_path_buf()).unwrap(); | ||
| self.cache.value(&manifest_path) | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did you try caching by cached_path.to_path_bug().parent()? All files from a same folder should have the same PnP manifest path (and find_closest_pnp_manifest_path accepts folders).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll check this out 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like using the parent makes these tests fail for some reason: 😬
---- tests::pnp::pnp1 stdout ----
thread 'tests::pnp::pnp1' panicked at src/tests/pnp.rs:19:5:
assertion `left == right` failed
left: Err(NotFound("is-even"))
right: Ok("/Users/julien.elbaz/dev/experiments/rspack-resolver/fixtures/pnp/.yarn/cache/is-even-npm-1.0.0-9f726520dc-2728cc2f39.zip/node_modules/is-even/index.js")
---- tests::pnp::resolve_in_pnp_linked_folder stdout ----
thread 'tests::pnp::resolve_in_pnp_linked_folder' panicked at src/tests/pnp.rs:106:5:
assertion `left == right` failed
left: Err(NotFound("lib/lib.js"))
right: Ok("/Users/julien.elbaz/dev/experiments/rspack-resolver/fixtures/pnp/shared/lib.js")
I'll leave this optimization out for the moment.
CodSpeed Performance ReportMerging #69 will improve performances by ×5.2Comparing Summary
Benchmarks breakdown
|
|
hi @elbywan thank you for your great work! Later, will move the pnp functions to |
nice job! |
Goal
In a nutshell: this PR aims to fix a huge memory consumption issue when using the pnp feature in a large codebase.
As of today the Plug'n'Play manifest is read/deserialized from the
.pnp.cjsfile into a struct which is then cached by the path of the file containing theimport/requirestatement. Is seems inefficient since the path can change a lot for large codebases even though the manifest contents are ultimately the same.This PR changes the code to use the path of the manifest itself as the key to avoid storing the same manifest multiple times.
Context
In my current company we are in the process of migrating from
esbuildtorspackto build our frontend assets in a huge monorepo (>10 millions LOC). We are also experimenting with Module Federation.Our rspack build pipeline works well except when enabling the Module Federation plugin, memory consumption goes through the roof quickly reaching 128+Gb on my machine.
I noticed that one of the main difference between these runs is that we are using our own custom resolver plugin based on
enhanced-resolvewhereas Module Federation heavily usesrspack-resolverlike here.In order to pinpoint the issue I used the instruments osx app to profile the build and monitor the allocations, and here are some results that prompted me to make these changes:
Heavy memory consumption
The load_pnp_manifest() method is called in a redundant way
With this fix: no more memory leak