Skip to content

Commit bb09531

Browse files
authored
perf(cache): skip async state-machine on OnceCell cache hit (#224)
1 parent 84478a9 commit bb09531

1 file changed

Lines changed: 29 additions & 0 deletions

File tree

src/cache.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ impl CachedPathImpl {
184184
}
185185

186186
async fn meta<Fs: Send + Sync + FileSystem>(&self, fs: &Fs) -> Option<FileMetadata> {
187+
// Skip the Future state-machine + poll on cache hit. `tokio::sync::OnceCell::get`
188+
// is sync and bypasses constructing the `get_or_init` future entirely.
189+
if let Some(m) = self.meta.get() {
190+
return *m;
191+
}
187192
*self
188193
.meta
189194
.get_or_init(|| async { fs.metadata(&self.path).await.ok() })
@@ -215,6 +220,15 @@ impl CachedPathImpl {
215220
fs: &'a Fs,
216221
) -> BoxFuture<'a, io::Result<PathBuf>> {
217222
let fut = async move {
223+
// Cache hit: return immediately and avoid the recursive parent walk +
224+
// `Box::pin` per call on the hot path.
225+
if let Some(cached) = self.canonicalized.get() {
226+
return Ok(
227+
cached
228+
.clone()
229+
.unwrap_or_else(|| self.path.clone().to_path_buf()),
230+
);
231+
}
218232
self
219233
.canonicalized
220234
.get_or_try_init(|| async move {
@@ -258,6 +272,9 @@ impl CachedPathImpl {
258272
cache: &Cache<Fs>,
259273
ctx: &mut Ctx,
260274
) -> Option<CachedPath> {
275+
if let Some(nm) = self.node_modules.get() {
276+
return nm.clone();
277+
}
261278
self
262279
.node_modules
263280
.get_or_init(|| self.module_directory("node_modules", cache, ctx))
@@ -308,6 +325,18 @@ impl CachedPathImpl {
308325
options: &ResolveOptions,
309326
ctx: &mut Ctx,
310327
) -> Result<Option<Arc<PackageJson>>, ResolveError> {
328+
if let Some(pkg) = self.package_json.get() {
329+
// Preserve ctx dependency tracking on cache hit.
330+
match pkg {
331+
Some(package_json) => ctx.add_file_dependency(&package_json.path),
332+
None => {
333+
if let Some(deps) = &mut ctx.missing_dependencies {
334+
deps.push(self.path.join("package.json"));
335+
}
336+
}
337+
}
338+
return Ok(pkg.clone());
339+
}
311340
// Change to `std::sync::OnceLock::get_or_try_init` when it is stable.
312341
let result = self
313342
.package_json

0 commit comments

Comments
 (0)