Skip to content
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

forc-pkg: Refactor BuildPlan construction and validation to minimize fetching, improve offline support, reduce I/O, fix bugs. #2234

Merged
merged 40 commits into from
Jul 6, 2022

Conversation

mitchmindtree
Copy link
Contributor

@mitchmindtree mitchmindtree commented Jul 6, 2022

This continues @kayagokalp's great work on #1974 with a wider overhaul of the package graph BuildPlan validation and construction.

BuildPlan refactor

During kaya's work on #1974 it became clear we needed to reconsider the approach to package graph validation in order to be able to more generally account for all of the different ways a node might have been invalidated since the lock file was last written, and to be able to handle invalidated nodes in a more consistent manner.

This refactors the build plan construction process into the following distinct steps:

  1. Load the project manifest.
  2. Load the project lock.
  3. Convert the lock to a package graph.
  4. Validate the package graph, collecting all invalid nodes. A node is invalid if:
    • We are unable to construct its local path.
    • We are unable to load its manifest.
    • It is no longer present within its parent's manifest.
    • Its Source differs from the source or patch described in the parent's manifest.
    • Its name differs from the name within its manifest.
  5. Remove all invalid nodes and any remaining nodes with no valid parents. Remaining nodes are known to be valid.
  6. Fetch the missing components of the graph until it is complete. If in offline, only fail if we are missing a git node.
  7. Determine the compilation order.

Closes #1903.
Closes #1778.
Makes progress on #895, #1787.

PathMap ManifestMap

This PR also reduces the number of times that we need to read each dependency's manifest from file in order to reduce the amount of I/O performed. Each dependency's manifest should now be loaded once during either graph_to_manifest_map or fetch_graph.

This required implementing Clone for ManifestFile to allow for constructing the build plan in a manner that does not require consuming the manifest file. ManifestFile::clone is only ever called for the project manifest, and never for the dependencies.

As a side-effect, the build and check commands no longer require loading each package's manifest as they are already provided by the build plan. As a result both commands no longer require the sway git tag to be passed through.

kayagokalp and others added 30 commits June 14, 2022 20:26
Co-authored-by: mitchmindtree <mitchell.nordine@fuel.sh>
This commit reduces the number of times that we need to read each
dependency's manifest from file in order to reduce the amount of I/O
performed. Each dependency's manifest should now only be loaded once
during either `graph_to_manifest_map` or `fetch_graph`.

This required implementing `Clone` for `ManifestFile` to allow for
constructing the build plan in a manner that does not require consuming
the manifest file. `ManifestFile::clone` should only ever be called for
the root node.

As a side-effect, the `build` and `check` commands no longer require
loading each package's manifest as they are already provided by the
build plan. As a result both commands no longer require the sway git
tag to be passed through.
@mitchmindtree mitchmindtree changed the title forc-pkg: Refactor BuildPlan construction and validation to minimize fetching, improve offline support, reduce I/O. forc-pkg: Refactor BuildPlan construction and validation to minimize fetching, improve offline support, reduce I/O, fix bugs. Jul 6, 2022
Previously, all dependency nodes were removed in the case that they were
invalid for any one of their parents.

This commit changes the behaviour to not remove the node, but rather
each invalid dependency *edge* instead. This means that if a node is
valid for one parent but not another, only the edge to the other parent
is removed and not the whole node itself. The node is only removed in
the case that it is invalid for all of its parents.

This is necessary for handling the case where a dependency no longer
exists in one parent's `[dependencies]` but still exists in another. The
most common case for this is `std`, as many nodes may depend on `std`
however we don't want to remove `std` and have to re-fetch it just
because one of the nodes removed their depenency on it.
@mitchmindtree mitchmindtree force-pushed the mitchmindtree/build-plan-refactor branch from 6daaea1 to 02ceb92 Compare July 6, 2022 04:11
@mitchmindtree mitchmindtree marked this pull request as ready for review July 6, 2022 05:38
@mitchmindtree mitchmindtree requested review from a team, JoshuaBatty and kayagokalp July 6, 2022 05:38
@mitchmindtree mitchmindtree enabled auto-merge (squash) July 6, 2022 05:58
kayagokalp
kayagokalp previously approved these changes Jul 6, 2022
Copy link
Member

@kayagokalp kayagokalp left a comment

Choose a reason for hiding this comment

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

Looks good to me 🙌 , just left a small nit (which is not a blocker, just a simple typo).

Also a side note I realized the build process is considerably faster (while adding a new dep) with this PR. A small benchmark on my m1 MBA:

Adding dep (existing Forc.lock) before this PR: 3.18 seconds
Adding dep (existing Forc.lock) with this PR: 0.79 seconds

forc-pkg/src/pkg.rs Outdated Show resolved Hide resolved
@kayagokalp kayagokalp requested a review from a team July 6, 2022 12:08
Co-authored-by: Kaya Gökalp <kayagokalp@sabanciuniv.edu>
@adlerjohn
Copy link
Contributor

Should this be merged into #1974 instead of master?

@JoshuaBatty
Copy link
Member

I think it's fine to merge this into master and close #1974.

Copy link
Member

@JoshuaBatty JoshuaBatty left a comment

Choose a reason for hiding this comment

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

Nice work. Looks good.

@mitchmindtree mitchmindtree merged commit fbeba25 into master Jul 6, 2022
@mitchmindtree mitchmindtree deleted the mitchmindtree/build-plan-refactor branch July 6, 2022 23:50
@mitchmindtree
Copy link
Contributor Author

Should this be merged into #1974 instead of master?

Ah I should have clarified this in my OP a bit further! I decided to base directly against master as the diff was just about as large compared to #1974 as it was to master, so I thought I'd try saving on the intermediary review. But you're right and I agree, in most cases it's better to base against the existing PR when possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working code quality dependencies enhancement New feature or request forc
Projects
Archived in project
5 participants