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

Restart at most once when prepopulating repository rule environment #20434

Conversation

Silic0nS0ldier
Copy link
Contributor

When a repository rule is fetch attributes are iterated over in enforceLabelAttributes to prepopulate the environment, restarting the fetch each time a new dependency is discovered.

This is faster than calling repository_ctx.path(...) early in the repository rule implementation function but still has considerable overhead.

This PR defers throwing NeedsSkyframeRestartException till after every attribute has been processed, greatly reducing the number of restarts and iterations.

In an internal project these optimisations are particularly noticeable.
Before: 2min 8s, 2min 7s
After: 1min 35s, 1min 27s

@github-actions github-actions bot added team-ExternalDeps External dependency handling, remote repositiories, WORKSPACE file. awaiting-review PR is awaiting review from an assigned reviewer labels Dec 5, 2023
@fmeum
Copy link
Collaborator

fmeum commented Dec 5, 2023

This also allows downloads of label{_list} dependencies to be performed in parallel, which is nice.

The ideal solution would probably be to turn StarlarkBaseExternalContext#getPathFromLabel into a function that accepts a list of Labels and uses env.getValuesAndExceptions throughout for "batched" Skyframe requests, but that would require a larger refactoring. This looks like a much simpler fix that should give most of the same benefits.

CC @Wyverald

@meteorcloudy meteorcloudy requested a review from Wyverald December 5, 2023 15:35
Copy link
Member

@Wyverald Wyverald left a comment

Choose a reason for hiding this comment

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

nice, thank you!

@Wyverald Wyverald added awaiting-PR-merge PR has been approved by a reviewer and is ready to be merge internally and removed awaiting-review PR is awaiting review from an assigned reviewer labels Dec 5, 2023
@fmeum
Copy link
Collaborator

fmeum commented Dec 5, 2023

@bazel-io flag

@bazel-io bazel-io added the potential release blocker Flagged by community members using "@bazel-io flag". Should be added to a release blocker milestone label Dec 5, 2023
@iancha1992
Copy link
Member

@bazel-io fork 7.1.0

@bazel-io bazel-io removed the potential release blocker Flagged by community members using "@bazel-io flag". Should be added to a release blocker milestone label Dec 5, 2023
@iancha1992
Copy link
Member

iancha1992 commented Dec 5, 2023

@fmeum @Wyverald I will put this for 7.1.0 for now since it does not look like a regression
cc: @bazelbuild/triage

@copybara-service copybara-service bot closed this in e8ac96a Dec 5, 2023
@github-actions github-actions bot removed the awaiting-PR-merge PR has been approved by a reviewer and is ready to be merge internally label Dec 5, 2023
@Silic0nS0ldier
Copy link
Contributor Author

since it does not look like a regression

To confirm, this is not a fix for a regression (at least not a recent one since Bazel 6.4.0 also benefits).


The ideal solution would probably be to turn StarlarkBaseExternalContext#getPathFromLabel into a function that accepts a list of Labels and uses env.getValuesAndExceptions throughout for "batched" Skyframe requests, but that would require a larger refactoring.

Would be more efficient and likely require less code. I think it would make sense to batch that work with resolving // TODO(wyv): somehow migrate this to the base context too..

Looking at src/main/java/com/google/devtools/build/lib/bazel/repository/starlark/StarlarkRepositoryFunction.java#fetchInternal there are plenty of places where null is returned (indicating a restart is required). There may yet be more restarts that can be eliminated.


I see that this has been tagged for Bazel 7.1. Any chance this can be included in the next v6 release?

@iancha1992
Copy link
Member

cc: @Wyverald @meteorcloudy

@meteorcloudy
Copy link
Member

Any chance this can be included in the next v6 release?

We don't have 6.5 release planned. By our release policy, we'll no longer backport features to the previous LTS when a new one is out, only critical bug fixes. We might reconsider if there are actually enough interests for a new 6.5 release if that helps with the migration to 7.

bazel-io pushed a commit to bazel-io/bazel that referenced this pull request Dec 21, 2023
When a repository rule is fetch attributes are iterated over in `enforceLabelAttributes` to prepopulate the environment, restarting the fetch each time a new dependency is discovered.

This is faster than calling `repository_ctx.path(...)` early in the repository rule implementation function but still has considerable overhead.

This PR defers throwing `NeedsSkyframeRestartException` till after every attribute has been processed, greatly reducing the number of restarts and iterations.

In an internal project these optimisations are particularly noticeable.
Before: 2min 8s, 2min 7s
After: 1min 35s, 1min 27s

Closes bazelbuild#20434.

PiperOrigin-RevId: 588090528
Change-Id: I7917b137d6e60b6d6a73189cf396418a85b3ec28
@aignas
Copy link

aignas commented Dec 23, 2023

@meteorcloudy, since 6.5 has been decided to happen, is this PR something that you would be willing to include in the release? Having these performance improvements could be helpful in the context of rules authors needing to support non-latest bazel version and it may allow to not worry about the restarts as much.

@fmeum
Copy link
Collaborator

fmeum commented Dec 23, 2023

@bazel-io fork 6.5.0

bazel-io pushed a commit to bazel-io/bazel that referenced this pull request Dec 23, 2023
When a repository rule is fetch attributes are iterated over in `enforceLabelAttributes` to prepopulate the environment, restarting the fetch each time a new dependency is discovered.

This is faster than calling `repository_ctx.path(...)` early in the repository rule implementation function but still has considerable overhead.

This PR defers throwing `NeedsSkyframeRestartException` till after every attribute has been processed, greatly reducing the number of restarts and iterations.

In an internal project these optimisations are particularly noticeable.
Before: 2min 8s, 2min 7s
After: 1min 35s, 1min 27s

Closes bazelbuild#20434.

PiperOrigin-RevId: 588090528
Change-Id: I7917b137d6e60b6d6a73189cf396418a85b3ec28
github-merge-queue bot pushed a commit that referenced this pull request Jan 9, 2024
…onment (#20667)

When a repository rule is fetch attributes are iterated over in
`enforceLabelAttributes` to prepopulate the environment, restarting the
fetch each time a new dependency is discovered.

This is faster than calling `repository_ctx.path(...)` early in the
repository rule implementation function but still has considerable
overhead.

This PR defers throwing `NeedsSkyframeRestartException` till after every
attribute has been processed, greatly reducing the number of restarts
and iterations.

In an internal project these optimisations are particularly noticeable.
Before: 2min 8s, 2min 7s
After: 1min 35s, 1min 27s

Closes #20434.

Commit
e8ac96a

PiperOrigin-RevId: 588090528
Change-Id: I7917b137d6e60b6d6a73189cf396418a85b3ec28

Co-authored-by: Jordan Mele <mele@canva.com>
Co-authored-by: Xùdōng Yáng <wyverald@gmail.com>
github-merge-queue bot pushed a commit that referenced this pull request Jan 9, 2024
…onment (#20643)

When a repository rule is fetch attributes are iterated over in
`enforceLabelAttributes` to prepopulate the environment, restarting the
fetch each time a new dependency is discovered.

This is faster than calling `repository_ctx.path(...)` early in the
repository rule implementation function but still has considerable
overhead.

This PR defers throwing `NeedsSkyframeRestartException` till after every
attribute has been processed, greatly reducing the number of restarts
and iterations.

In an internal project these optimisations are particularly noticeable.
Before: 2min 8s, 2min 7s
After: 1min 35s, 1min 27s

Closes #20434.

Commit
e8ac96a

PiperOrigin-RevId: 588090528
Change-Id: I7917b137d6e60b6d6a73189cf396418a85b3ec28

Co-authored-by: Jordan Mele <mele@canva.com>
Co-authored-by: Xùdōng Yáng <wyverald@gmail.com>
@iancha1992
Copy link
Member

The changes in this PR have been included in Bazel 6.5.0 RC1. Please test out the release candidate and report any issues as soon as possible. If you're using Bazelisk, you can point to the latest RC by setting USE_BAZEL_VERSION=last_rc.
Thanks!

@Silic0nS0ldier
Copy link
Contributor Author

Tested 6.5.0rc1 locally (macOS) and on CI (Linux), no issues.

Change is working as advertised too. Local test case finished about a minute faster.

@iancha1992
Copy link
Member

The changes in this PR have been included in Bazel 7.1.0 RC1. Please test out the release candidate and report any issues as soon as possible. If you're using Bazelisk, you can point to the latest RC by setting USE_BAZEL_VERSION=last_rc.
Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
team-ExternalDeps External dependency handling, remote repositiories, WORKSPACE file.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants