[WIP] Rewrite DeltaBundler cycle collection as a separate pass#820
Closed
motiz88 wants to merge 1 commit into
Closed
[WIP] Rewrite DeltaBundler cycle collection as a separate pass#820motiz88 wants to merge 1 commit into
motiz88 wants to merge 1 commit into
Conversation
Contributor
|
This pull request was exported from Phabricator. Differential Revision: D36403390 |
Summary: Pull Request resolved: react#820 See also: microsoft/rnx-kit#1514 Rewrites traverseDependencies (the core algorithm of DeltaBundler) to run in two distinct phases: 1. Module transformation + dependency discovery/diffing. 2. Garbage collection. Modules that are trivially unreachable (inverse dependency count decreases to zero) are deleted during (1); the rest ( = unreachable modules in dependency cycles) are deleted during (2). By collecting cycles in a separate pass instead of kicking off nested traversals during the dependency diffing pass, the algorithm becomes easier to reason about, and we gain the ability to optionally skip GC (in future work) because all the GC state is stored in the graph (and not on the traversal stack). The garbage collection code is adapted from the Synchronous Cycle Collection algorithm described in: > David F. Bacon and V. T. Rajan. 2001. Concurrent Cycle Collection in Reference Counted Systems. In Proceedings of the 15th European Conference on Object-Oriented Programming (ECOOP '01). Springer-Verlag, Berlin, Heidelberg, 207–235. --- As part of this rewrite we also make the handling of async imports under `experimentalImportBundleSupport: true` more sound and tested, at least as far as `traverseDependencies` goes. Several of the new tests under "lazy traversal of async imports" were failing before this diff. Note that there a few remaining problems with this experimental feature, which will need to be fixed in separate work: 1. The HMR protocol does not sync changes to `importBundleNames` between the client and server, so any newly added async dependencies in a Fast Refresh'd module will (still) break at runtime. 2. A module's out-edges are keyed on the unresolved dependency paths only, so a parallel async+sync pair of dependencies from A --> B will result in either an async or sync edge being recorded, depending on their order in the dependencies array. This will need fixing in both DeltaBundler and `collectDependencies`. Differential Revision: D36403390 fbshipit-source-id: f56241d0c4c038b6c780cb58ca4d50e1bb0ff1fb
Contributor
|
This pull request was exported from Phabricator. Differential Revision: D36403390 |
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See also: microsoft/rnx-kit#1514
Rewrites traverseDependencies (the core algorithm of DeltaBundler) to run in two distinct phases:
Modules that are trivially unreachable (inverse dependency count decreases to zero) are deleted during (1); the rest ( = unreachable modules in dependency cycles) are deleted during (2).
By collecting cycles in a separate pass instead of kicking off nested traversals during the dependency diffing pass, the algorithm becomes easier to reason about, and we gain the ability to optionally skip GC (in future work) because all the GC state is stored in the graph (and not on the traversal stack).
The garbage collection code is adapted from the Synchronous Cycle Collection algorithm described in:
As part of this rewrite we also make the handling of async imports under
experimentalImportBundleSupport: truemore sound and tested, at least as far astraverseDependenciesgoes. Several of the new tests under "lazy traversal of async imports" were failing before this diff. Note that there a few remaining problems with this experimental feature, which will need to be fixed in separate work:importBundleNamesbetween the client and server, so any newly added async dependencies in a Fast Refresh'd module will (still) break at runtime.collectDependencies.Differential Revision: D36403390