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

Race condition when depending on rules created in post_build. #3168

Open
cemeceme opened this issue May 16, 2024 · 1 comment
Open

Race condition when depending on rules created in post_build. #3168

cemeceme opened this issue May 16, 2024 · 1 comment

Comments

@cemeceme
Copy link
Contributor

Here is an example of a BUILD file with a post_build function adding dependencies:

def post_func(ruleName, cmdOutput):
    fileRule = text_file(name="postFile", content = "Some content", out="postFile.txt")
    add_dep(ruleName, fileRule, True)

genrule(name="postRule", cmd="", post_build=post_func)

genrule(name="postRuleConsumer", cmd="", deps=[":postRule"])

Running this with plz build //:postRuleConsumer will result in an output of cannot calculate hash for plz-out/gen/postFile.txt: file does not exist.

However, if you somehow force post_func to run without dependents (in this case postRuleConsumer), for example by calling //:postRule on its own, then postFile.txt will get created.
Once the file is created, subsequent runs will start to succeed and have the file available until the next plz clean call.

What seems to be happening, is that the commands of rules in post_builds aren't getting executed. I have confirmed this by changing the text_file rule into genrule(name="postFile", cmd = "sleep 10; touch postFile.txt", out="postFile.txt"). When //:postRule is run on its own, it will take 10 seconds to run, however when run with //:postRuleConsumer the command will immediately finish, either with the same error, or by succeeding if //:postRule was run on its own beforehand.

@cemeceme
Copy link
Contributor Author

I have been looking into the code base to track down this issue, and found that it was actually a race condition.
It turns out that if there is another rule that can block the dependent rule until the post build completes, then everything works as expected. Otherwise, the same issue as mentioned occurs.

Here is an example build script that will succeed:

def post_func(ruleName, cmdOutput):
    fileRule = genrule(name="postFile", cmd = "sleep 10; touch postFile.txt", out="postFile.txt")
    add_dep(ruleName, fileRule, True)

genrule(name="postRule", cmd="", post_build=post_func)

genrule(name="waitRule", cmd="sleep 11; touch waitFile.txt", out="waitFile.txt")

genrule(name="postRuleConsumer", cmd="", deps=[":postRule", ":waitRule"])

Note the sleep 10 in the file rule and sleep 11 in the wait rule. As long as the "postFile" rule in this example completes before the "waitRule" everything works.

@cemeceme cemeceme changed the title Additional rules in post build functions don't get run properly. Race condition when depending on rules created in post_build. May 18, 2024
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

No branches or pull requests

1 participant