From 039461c76113ab3f165132dd26d0c58eb3e45cae Mon Sep 17 00:00:00 2001 From: larsrc Date: Tue, 19 Jan 2021 10:14:22 -0800 Subject: [PATCH] Adding debugging information for case when two branches apparently cancel each other. RELNOTES: None. PiperOrigin-RevId: 352596000 --- .../lib/dynamic/DynamicSpawnStrategy.java | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/dynamic/DynamicSpawnStrategy.java b/src/main/java/com/google/devtools/build/lib/dynamic/DynamicSpawnStrategy.java index ab4eea96344f38..97049f35695799 100644 --- a/src/main/java/com/google/devtools/build/lib/dynamic/DynamicSpawnStrategy.java +++ b/src/main/java/com/google/devtools/build/lib/dynamic/DynamicSpawnStrategy.java @@ -230,37 +230,43 @@ private static ImmutableList waitBranch(FutureThis guarantees that the two branches are stopped both on successful termination and on an * exception. * - * @param branch1 the future running one side of the spawn (e.g. local). This future must cancel - * {@code branch2} at some point during its successful execution to guarantee termination. If - * we encounter an execution error, or if we are interrupted, then we handle such cancellation - * here. - * @param branch2 the future running the other side of the spawn (e.g. remote). Same restrictions - * apply as in {@code branch1}, but in the symmetric direction. + * @param localBranch the future running the local side of the spawn. This future must cancel + * {@code remoteBranch} at some point during its successful execution to guarantee + * termination. If we encounter an execution error, or if we are interrupted, then we handle + * such cancellation here. + * @param remoteBranch the future running the remote side of the spawn. Same restrictions apply as + * in {@code localBranch}, but in the symmetric direction. * @return the result of the branch that terminates first * @throws ExecException the execution error of the spawn that terminated first * @throws InterruptedException if we get interrupted while waiting for completion */ private static ImmutableList waitBranches( - Future> branch1, Future> branch2) + Future> localBranch, + Future> remoteBranch) throws ExecException, InterruptedException { - ImmutableList result1; + ImmutableList localResult; try { - result1 = waitBranch(branch1); + localResult = waitBranch(localBranch); } catch (ExecException | InterruptedException | RuntimeException e) { - branch2.cancel(true); + remoteBranch.cancel(true); throw e; } - ImmutableList result2 = waitBranch(branch2); + ImmutableList remoteResult = waitBranch(remoteBranch); - if (result2 != null && result1 != null) { + if (remoteResult != null && localResult != null) { throw new AssertionError("One branch did not cancel the other one"); - } else if (result2 != null) { - return result2; - } else if (result1 != null) { - return result1; + } else if (remoteResult != null) { + return remoteResult; + } else if (localResult != null) { + return localResult; } else { - throw new AssertionError("No branch completed, which might mean they cancelled each other"); + throw new AssertionError( + "Neither branch completed. Local was " + + (localBranch.isCancelled() ? "" : "not ") + + "cancelled and remote was " + + (remoteBranch.isCancelled() ? "" : "not ") + + "cancelled"); } }