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

Fix watching paths in undefined repos in repo rules #21562

Closed
wants to merge 1 commit into from

Conversation

Wyverald
Copy link
Member

@Wyverald Wyverald commented Mar 4, 2024

Watching a path in an undefined repo (eg. $output_base/external/i_am_undefined/blah) currently causes an NPE because we expect it to need a skyframe restart when it actually doesn't. The underlying reason is rather convoluted, but the gist is that we request RepositoryDirectoryValue.Key(@@i_am_undefined) explicitly, when we don't actually have to -- we can simply use FileValue.Key($output_base/external/i_am_undefined/blah directly, and rely on the fact that FileFunction knows to request the corresponding RepositoryDirectoryValue and behave appropriately when the repo is undefined. (This is due to logic in ExternalFilesHelper.maybeHandleExternalFile.)

Additionally, this PR removes the rctx.symlink(watch_target=) parameter. The symlink target's existence and its contents should not affect the creation of the symlink at all, so there's no reason to ever watch it.

Fixes #21483.

Watching a path in an undefined repo (eg. `$output_base/external/i_am_undefined/blah`) currently causes an NPE because we expect it to need a skyframe restart when it actually doesn't. The underlying reason is rather convoluted, but the gist is that we request `RepositoryDirectoryValue.Key(@@i_am_undefined)` explicitly, when we don't actually have to -- we can simply use `FileValue.Key($output_base/external/i_am_undefined/blah` directly, and rely on the fact that `FileFunction` knows to request the corresponding `RepositoryDirectoryValue` and behave appropriately when the repo is undefined. (This is due to logic in `ExternalFilesHelper.maybeHandleExternalFile`.)

Additionally, this PR removes the `rctx.symlink(watch_target=)` parameter. The symlink target's existence and its contents should not affect the creation of the symlink at all, so there's no reason to ever watch it.

Fixes #21483.
@Wyverald Wyverald requested a review from lberki as a code owner March 4, 2024 22:07
@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 Mar 4, 2024
Copy link
Collaborator

@fmeum fmeum left a comment

Choose a reason for hiding this comment

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

... currently causes an NPE because we expect it to need a skyframe restart when it actually doesn't.

The changes look good to me, but couldn't this NPE still show up if something is available in Skyframe that we didn't expect to be ready? I would sleep better with logic preventing that entirely.

@Wyverald
Copy link
Member Author

Wyverald commented Mar 4, 2024

... currently causes an NPE because we expect it to need a skyframe restart when it actually doesn't.

The changes look good to me, but couldn't this NPE still show up if something is available in Skyframe that we didn't expect to be ready? I would sleep better with logic preventing that entirely.

Not sure what you mean here -- I was referring to the case where RepoCacheFriendlyPath.getRootedPath() returns null but actually doesn't need a Skyframe restart (ie. when the repo doesn't exist here).

@fmeum
Copy link
Collaborator

fmeum commented Mar 5, 2024

Ah, I see, then I agree we don't need to do anything more.

@meteorcloudy meteorcloudy 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 Mar 5, 2024
@lberki
Copy link
Contributor

lberki commented Mar 5, 2024

The code looks reasonable as far as I can tell (although I managed to code myself silly today), but do we want to allow repositories to depend on files in non-existent other repositories?

Until now, depending on non-existent repositories caused an error and you are breaking this invariant. I'd rather not because, well, it's another avenue for creativity.

@Wyverald
Copy link
Member Author

Wyverald commented Mar 5, 2024

Until now, depending on non-existent repositories caused an error and you are breaking this invariant. I'd rather not because, well, it's another avenue for creativity.

I don't think any invariant is being broken because until now there was no way to "depend on non-existent repositories" at all -- rctx.watch is a new API. Trying to rctx.read a nonexistent path (whether in an undefined repo or any other nonexistent path) will still result in an error.

@copybara-service copybara-service bot closed this in aba1186 Mar 5, 2024
@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 Mar 5, 2024
bazel-io pushed a commit to bazel-io/bazel that referenced this pull request Mar 5, 2024
Watching a path in an undefined repo (eg. `$output_base/external/i_am_undefined/blah`) currently causes an NPE because we expect it to need a skyframe restart when it actually doesn't. The underlying reason is rather convoluted, but the gist is that we request `RepositoryDirectoryValue.Key(@@i_am_undefined)` explicitly, when we don't actually have to -- we can simply use `FileValue.Key($output_base/external/i_am_undefined/blah` directly, and rely on the fact that `FileFunction` knows to request the corresponding `RepositoryDirectoryValue` and behave appropriately when the repo is undefined. (This is due to logic in `ExternalFilesHelper.maybeHandleExternalFile`.)

Additionally, this PR removes the `rctx.symlink(watch_target=)` parameter. The symlink target's existence and its contents should not affect the creation of the symlink at all, so there's no reason to ever watch it.

Fixes bazelbuild#21483.

Closes bazelbuild#21562.

PiperOrigin-RevId: 612898526
Change-Id: I30deb9d9b2d19e0869517f4b6b126078446745b4
@Wyverald Wyverald deleted the wyv-fix-watch-undefined branch March 5, 2024 18:59
@lberki
Copy link
Contributor

lberki commented Mar 5, 2024

Before this change, you couldn't say "please inform me if this non-existent repo springs into existence", now you can, if I understand correctly.

I haven't gamed out all the ways this could go wrong, but it looks like a lot of rope to me. I might be overly cautious here, but is there any reason to allow this functionality as opposed to just bailing out if one tries to watch a file in another repository, which does not exist?

@Wyverald
Copy link
Member Author

Wyverald commented Mar 5, 2024

I see... I don't think there's any explicit reason to allow it; it just happened naturally because that's what FileFunction does. Presumably the same could happen through any other FileFunction dependency on something in $output_base/external, though I don't know if that's possible outside of repo rules. Maybe we could just make RepositoryFunction.addExternalFilesDependencies() throw an exception if the repo in question is undefined. WDYT?

github-merge-queue bot pushed a commit that referenced this pull request Mar 5, 2024
Watching a path in an undefined repo (eg.
`$output_base/external/i_am_undefined/blah`) currently causes an NPE
because we expect it to need a skyframe restart when it actually
doesn't. The underlying reason is rather convoluted, but the gist is
that we request `RepositoryDirectoryValue.Key(@@i_am_undefined)`
explicitly, when we don't actually have to -- we can simply use
`FileValue.Key($output_base/external/i_am_undefined/blah` directly, and
rely on the fact that `FileFunction` knows to request the corresponding
`RepositoryDirectoryValue` and behave appropriately when the repo is
undefined. (This is due to logic in
`ExternalFilesHelper.maybeHandleExternalFile`.)

Additionally, this PR removes the `rctx.symlink(watch_target=)`
parameter. The symlink target's existence and its contents should not
affect the creation of the symlink at all, so there's no reason to ever
watch it.

Fixes #21483.

Closes #21562.

Commit
aba1186

PiperOrigin-RevId: 612898526
Change-Id: I30deb9d9b2d19e0869517f4b6b126078446745b4

Co-authored-by: Xdng Yng <wyverald@gmail.com>
@lberki
Copy link
Contributor

lberki commented Mar 5, 2024

I'm afraid it's too late here for me to think through all the ramifications, but in general, we should either think through the consequences of behavior we allow or disallow it. The latter seems to be much simpler.

re: making addExternalFilesDependencies(), if anything breaks, my guess would be that it's when there is a symlink under a source root to such an undefined repository. I don't see any reason why anyone would possibly want to create such a symlink, so I'm for prohibiting it. If it doesn't work for some reason, hopefully our test battery will signal.

@Wyverald
Copy link
Member Author

Wyverald commented Mar 5, 2024

it's when there is a symlink under a source root to such an undefined repository.

ah, indeed -- so it's already possible today. IMO that lowers the priority of this drastically. Depending on the existence of a repo name through rctx.watch is exactly as nonsensical as having a symlink into that path. I'll send a change, but won't block 7.1.0 on it.

@lberki
Copy link
Contributor

lberki commented Mar 6, 2024

SGTM. I'd be worried if it was a regression, but it's not.

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.1.0rc1 crashes with Unrecoverable error while evaluating node REPOSITORY_DIRECTORY
4 participants