Skip to content

fix(optimizer): settle pending processing promises on close() - #22935

Draft
bent0b0x wants to merge 2 commits into
vitejs:mainfrom
bent0b0x:fix/optimizer-close-settle-processing
Draft

bent0b0x wants to merge 2 commits into
vitejs:mainfrom
bent0b0x:fix/optimizer-close-settle-processing

Conversation

@bent0b0x

Copy link
Copy Markdown

Description

createDepsOptimizer().close() cancels the in-flight scan/optimize but does not resolve the current or enqueued depOptimizationProcessing promises. If a dependency is discovered into the current batch while an optimize run is in flight (after that run's startNextDiscoveredBatch() but before it finishes) and the server is then closed, that dep's optimizedDepInfo.processing is left pending forever. Its vite:optimized-deps load() awaits info.processing forever, so the request never leaves environment._pendingRequests and DevEnvironment.close()'s pending-request drain loop never completes — close() never resolves and the process hangs at teardown.

This mirrors runOptimizer()'s pre-optimize closed guard, which already resolves both the current and the enqueued promises; close() just needs to do the same.

Fixes #22934.

Reproduction

Minimal, deterministic repro (Vitest browser mode): https://github.com/bent0b0x/vite-optimizer-orphan-hang — npm test hangs on unpatched vite (reproduced on 8.0.8 and 8.1.4); applying this change makes it exit cleanly.

Note on tests

The failure is a teardown timing race — a dependency discovered mid-optimize plus close() landing while that optimize run is in flight — which is hard to express as a stable unit test without artificial timing hooks. The linked reproduction triggers it deterministically. Happy to add a test in whatever form maintainers prefer.

bent0b0x added 2 commits July 14, 2026 12:33
createDepsOptimizer().close() cancels the in-flight scan/optimize but does not
resolve the current or enqueued depOptimizationProcessing promises. A dependency
discovered into the current batch while an optimize run is in flight then keeps a
forever-pending optimizedDepInfo.processing, so its vite:optimized-deps load()
awaits info.processing forever and DevEnvironment.close()'s pending-request drain
never completes -> close() never resolves.

Mirror runOptimizer()'s pre-optimize closed guard, which already resolves both.

Fixes vitejs#22934

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.

server.close() hangs forever when a dependency is discovered mid-optimize (optimizer never settles its processing promise)

1 participant