buck2
buck2 copied to clipboard
Sometimes fixing a cyclic dependency requires a `buck2 killall`
I wish I could provide a minimal repro of this. I've tried and have been unable to figure it out.
Often times I introduce a cycle in my dependency tree. I do a build, and the build almost completes, and then at the very last step after almost all actions are run, I get an error saying there was a cycle. I go and fix the cycle by simply deleting one of the deps in one of the targets to break it. But buck2 immediately complains about a cycle again. No matter what I do, I cannot get it to keep running. If I do a buck2 killall
and then re-run the build, without touching any other files, it (strangely) restarts the entire build. All actions re-run. Then at the end, it doesn't complain about the cyclic dependency.
I'm going to keep working on a repro, as I can't provide my actual graph. But hopefully someone who understands the internals well can get an idea from this alone. It seems like it's caching something about the dependency tree and not properly invalidating it when the configuration changes.
We are in the process of moving from DICE to modern DICE (basically v2 of DICE). The way that cycles etc work between the two is quite different. I'm not that sure which open source ends up defaulting to. CC @cjhopman who has inherited DICE ownership and did a lot of work on the cycle tracking.
Do you know which format the cycle error is? We have two things that detect cycles, one prints the cycle all on one line and its hard to read and the other prints them with each node in the cycle on it's own line.
i.e.:
a -> b -> c -> d
vs
-> a
-> b
-> c
-> d
it'd help narrow this down if you knew which of the two it is.
I think this is eager deps causing spurious cycles, not related to the cycle detectors
Ah, yeah. That seems most likely.
It’s the single line version for sure. Another thing Ive occasionally noticed is that it will mention the same dep twice in a row. Like A > B > B > C > A, which is weird
can you elaborate on eager deps? The cycle is definitely there, it’s just that removing it doesn’t make the error go away without a restart
The eager deps is the problem is explained a bit in https://neilmitchell.blogspot.com/2020/11/data-types-for-build-system-dependencies.html. Imagine if instead of doing it the way Shake does, you just evaluated all previous dependencies in parallel, even if a previous dependency means they might not be possibly required. That causes all kind of weird things to happen, including cycles that can never be hit in the normal course of execution. Buck2 currently does that, and we call it the eager deps bug.
I see. Is there a plan to fix it somehow?
There are two plausible plans:
- Have a more refined dependency structure, and then only spawn the right things. Basically copy what Shake does.
- Have better cycle detection that is aware that there are potentially unreachable states. Shake actually also does this because it has non-deterministic dependency generators (which Buck2 doesn't have as much)
I believe @cjhopman plans to do number 1.