Replace anonymous classes with lambdas when possible. Most of these changes are for anonymous `SkyFunction` subclasses, and so they were enabled by commit 927b625e15d2beac5bfecae1d3c05783151a8ff3. (janakr@ therefore had recommended these changes during offline discussion about commit d789eda7fb9ee1b24ff643d65fd5794a920d61af.) Also make a few minor code cleanups. PiperOrigin-RevId: 414553549
diff --git a/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java b/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java index ffb21f8..7b47630 100644 --- a/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java +++ b/src/test/java/com/google/devtools/build/skyframe/MemoizingEvaluatorTest.java
@@ -54,6 +54,7 @@ import com.google.devtools.build.skyframe.NotifyingHelper.Listener; import com.google.devtools.build.skyframe.NotifyingHelper.Order; import com.google.devtools.build.skyframe.SkyFunction.Environment; +import com.google.devtools.build.skyframe.SkyFunction.Restart; import com.google.devtools.build.skyframe.SkyFunctionException.Transience; import com.google.devtools.build.skyframe.ThinNodeEntry.DirtyType; import com.google.devtools.build.skyframe.proto.GraphInconsistency.Inconsistency; @@ -249,32 +250,26 @@ tester .getOrCreate("top") .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException { - env.getValue(toSkyKey("sleepyValue")); - try { - env.getValueOrThrow(toSkyKey("badValue"), SomeErrorException.class); - } catch (SomeErrorException e) { - // In order to trigger this bug, we need to request a dep on an already computed - // value. - env.getValue(toSkyKey("otherValue1")); - } - if (!env.valuesMissing()) { - throw new AssertionError("SleepyValue should always be unavailable"); - } - return null; + (skyKey, env) -> { + env.getValue(toSkyKey("sleepyValue")); + try { + env.getValueOrThrow(toSkyKey("badValue"), SomeErrorException.class); + } catch (SomeErrorException e) { + // In order to trigger this bug, we need to request a dep on an already computed + // value. + env.getValue(toSkyKey("otherValue1")); } + if (!env.valuesMissing()) { + throw new AssertionError("SleepyValue should always be unavailable"); + } + return null; }); tester .getOrCreate("sleepyValue") .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException { - Thread.sleep(99999); - throw new AssertionError("I should have been interrupted"); - } + (skyKey, env) -> { + Thread.sleep(99999); + throw new AssertionError("I should have been interrupted"); }); tester.getOrCreate("badValue").addDependency("otherValue1").setHasError(true); tester.getOrCreate("otherValue1").setConstantValue(new StringValue("otherVal1")); @@ -293,16 +288,13 @@ tester .getOrCreate(topKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException { - if (counter.getAndIncrement() > 0) { - deps.addAll(env.getTemporaryDirectDeps().get(0)); - } else { - assertThat(env.getTemporaryDirectDeps().listSize()).isEqualTo(0); - } - return env.getValue(bottomKey); + (skyKey, env) -> { + if (counter.getAndIncrement() > 0) { + deps.addAll(env.getTemporaryDirectDeps().get(0)); + } else { + assertThat(env.getTemporaryDirectDeps().listSize()).isEqualTo(0); } + return env.getValue(bottomKey); }); tester.getOrCreate(bottomKey).setConstantValue(bottomValue); EvaluationResult<StringValue> result = tester.eval(/*keepGoing=*/ true, "top"); @@ -867,25 +859,22 @@ final SkyKey mid = GraphTester.toSkyKey("zzmid"); final CountDownLatch valueSet = new CountDownLatch(1); injectGraphListenerForTesting( - new Listener() { - @Override - public void accept(SkyKey key, EventType type, Order order, Object context) { - if (!key.equals(mid)) { - return; - } - switch (type) { - case ADD_REVERSE_DEP: - if (context == null) { - // Context is null when we are enqueuing this value as a top-level job. - TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions(valueSet, "value not set"); - } - break; - case SET_VALUE: - valueSet.countDown(); - break; - default: - break; - } + (key, type, order, context) -> { + if (!key.equals(mid)) { + return; + } + switch (type) { + case ADD_REVERSE_DEP: + if (context == null) { + // Context is null when we are enqueuing this value as a top-level job. + TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions(valueSet, "value not set"); + } + break; + case SET_VALUE: + valueSet.countDown(); + break; + default: + break; } }, /*deterministic=*/ true); @@ -1432,21 +1421,16 @@ // We don't do anything on the first build. final AtomicBoolean secondBuild = new AtomicBoolean(false); injectGraphListenerForTesting( - new Listener() { - @Override - public void accept(SkyKey key, EventType type, Order order, Object context) { - if (!secondBuild.get()) { - return; - } - if (key.equals(otherTop) && type == EventType.SIGNAL) { - // otherTop is being signaled that dep1 is done. Tell the error value that it is - // ready, then wait until the error is thrown, so that otherTop's builder is not - // re-entered. - valuesReady.countDown(); - TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( - errorThrown, "error not thrown"); - return; - } + (key, type, order, context) -> { + if (!secondBuild.get()) { + return; + } + if (key.equals(otherTop) && type == EventType.SIGNAL) { + // otherTop is being signaled that dep1 is done. Tell the error value that it is ready, + // then wait until the error is thrown, so that otherTop's builder is not re-entered. + valuesReady.countDown(); + TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions(errorThrown, "error not thrown"); + return; } }, /*deterministic=*/ true); @@ -1459,16 +1443,13 @@ tester .getOrCreate(otherTop) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException { - env.getValue(dep1); - if (env.valuesMissing()) { - return null; - } - env.getValue(dep2); - return env.valuesMissing() ? null : new StringValue("otherTop"); + (skyKey, env) -> { + env.getValue(dep1); + if (env.valuesMissing()) { + return null; } + env.getValue(dep2); + return env.valuesMissing() ? null : new StringValue("otherTop"); }); // Prime the graph with otherTop, so we can dirty it next build. assertThat(tester.evalAndGet(/*keepGoing=*/ false, otherTop)) @@ -1667,20 +1648,17 @@ tester .getOrCreate("subKey" + i) .setComputedValue( - new ValueComputer() { - @Override - public SkyValue compute(Map<SkyKey, SkyValue> deps, SkyFunction.Environment env) { - int val = inProgressCount.incrementAndGet(); - synchronized (lock) { - if (val > maxValue[0]) { - maxValue[0] = val; - } + (deps, env) -> { + int val = inProgressCount.incrementAndGet(); + synchronized (lock) { + if (val > maxValue[0]) { + maxValue[0] = val; } - Uninterruptibles.sleepUninterruptibly(5, TimeUnit.SECONDS); - - inProgressCount.decrementAndGet(); - return new StringValue("abc"); } + Uninterruptibles.sleepUninterruptibly(5, TimeUnit.SECONDS); + + inProgressCount.decrementAndGet(); + return new StringValue("abc"); }); } topLevelBuilder.setConstantValue(new StringValue("xyz")); @@ -2141,16 +2119,12 @@ tester .getOrCreate(topKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) - throws SkyFunctionException, InterruptedException { - env.getValues(ImmutableList.of(errorKey, midKey, mid2Key)); - if (env.valuesMissing()) { - return null; - } - return new StringValue("top"); + (skyKey, env) -> { + env.getValues(ImmutableList.of(errorKey, midKey, mid2Key)); + if (env.valuesMissing()) { + return null; } + return new StringValue("top"); }); // Assert that build fails and "error" really is in error. @@ -2182,23 +2156,19 @@ tester .getOrCreate(topKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) - throws SkyFunctionException, InterruptedException { - SkyKeyValue val = - ((SkyKeyValue) - env.getValues(ImmutableList.of(groupDepA, groupDepB)).get(groupDepA)); - if (env.valuesMissing()) { - return null; - } - try { - env.getValueOrThrow(val.key, SomeErrorException.class); - } catch (SomeErrorException e) { - throw new GenericFunctionException(e, Transience.PERSISTENT); - } - return env.valuesMissing() ? null : new StringValue("top"); + (skyKey, env) -> { + SkyKeyValue val = + ((SkyKeyValue) + env.getValues(ImmutableList.of(groupDepA, groupDepB)).get(groupDepA)); + if (env.valuesMissing()) { + return null; } + try { + env.getValueOrThrow(val.key, SomeErrorException.class); + } catch (SomeErrorException e) { + throw new GenericFunctionException(e, Transience.PERSISTENT); + } + return env.valuesMissing() ? null : new StringValue("top"); }); EvaluationResult<SkyValue> evaluationResult = tester.eval(/*keepGoing=*/ true, groupDepA, depC); @@ -2314,21 +2284,17 @@ tester .getOrCreate(top) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey key, SkyFunction.Environment env) - throws InterruptedException { - numTopInvocations.incrementAndGet(); - if (delayTopSignaling.get()) { - // The graph listener will block on firstKey's signaling of otherTop above until - // this thread starts running. - topRequestedDepOrRestartedBuild.countDown(); - } - // top's builder just requests both deps in a group. - env.getValuesOrThrow( - ImmutableList.of(firstKey, slowAddingDep), SomeErrorException.class); - return env.valuesMissing() ? null : new StringValue("top"); + (key, env) -> { + numTopInvocations.incrementAndGet(); + if (delayTopSignaling.get()) { + // The graph listener will block on firstKey's signaling of otherTop above until + // this thread starts running. + topRequestedDepOrRestartedBuild.countDown(); } + // top's builder just requests both deps in a group. + env.getValuesOrThrow( + ImmutableList.of(firstKey, slowAddingDep), SomeErrorException.class); + return env.valuesMissing() ? null : new StringValue("top"); }); // First build : just prime the graph. EvaluationResult<StringValue> result = tester.eval(/*keepGoing=*/ false, top); @@ -2408,21 +2374,18 @@ final CountDownLatch changedKeyCanFinish = new CountDownLatch(1); final AtomicBoolean controlTiming = new AtomicBoolean(false); injectGraphListenerForTesting( - new Listener() { - @Override - public void accept(SkyKey key, EventType type, Order order, Object context) { - if (!controlTiming.get()) { - return; - } - if (key.equals(midKey) && type == EventType.CHECK_IF_DONE && order == Order.BEFORE) { - TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( - changedKeyStarted, "changed key didn't start"); - } else if (key.equals(changedKey) - && type == EventType.REMOVE_REVERSE_DEP - && order == Order.AFTER - && midKey.equals(context)) { - changedKeyCanFinish.countDown(); - } + (key, type, order, context) -> { + if (!controlTiming.get()) { + return; + } + if (key.equals(midKey) && type == EventType.CHECK_IF_DONE && order == Order.BEFORE) { + TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( + changedKeyStarted, "changed key didn't start"); + } else if (key.equals(changedKey) + && type == EventType.REMOVE_REVERSE_DEP + && order == Order.AFTER + && midKey.equals(context)) { + changedKeyCanFinish.countDown(); } }, /*deterministic=*/ false); @@ -2497,16 +2460,7 @@ tester .getOrCreate(restartingKey) .setBuilder( - new SkyFunction() { - - @Override - public SkyValue compute(SkyKey skyKey, Environment env) { - if (numFunctionCalls.getAndIncrement() < 2) { - return Restart.SELF; - } - return expectedValue; - } - }); + (skyKey, env) -> numFunctionCalls.getAndIncrement() < 2 ? Restart.SELF : expectedValue); assertThat(tester.evalAndGet(/*keepGoing=*/ false, restartingKey)).isEqualTo(expectedValue); assertThat(numInconsistencyCalls.get()).isEqualTo(2); assertThat(numFunctionCalls.get()).isEqualTo(3); @@ -2566,26 +2520,23 @@ tester .getOrCreate(restartingKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException { - numFunctionCalls.getAndIncrement(); - SkyValue dep1 = env.getValue(alreadyRequestedDep); - if (dep1 == null) { - return null; - } - env.getValues(ImmutableList.of(newlyRequestedDoneDep, newlyRequestedNotDoneDep)); - if (numFunctionCalls.get() < 4) { - return Restart.SELF; - } else if (numFunctionCalls.get() == 4) { - if (cleanBuild.get()) { - Preconditions.checkState( - env.valuesMissing(), "Not done dep should never have been enqueued"); - } - return null; - } - return expectedValue; + (skyKey, env) -> { + numFunctionCalls.getAndIncrement(); + SkyValue dep1 = env.getValue(alreadyRequestedDep); + if (dep1 == null) { + return null; } + env.getValues(ImmutableList.of(newlyRequestedDoneDep, newlyRequestedNotDoneDep)); + if (numFunctionCalls.get() < 4) { + return Restart.SELF; + } else if (numFunctionCalls.get() == 4) { + if (cleanBuild.get()) { + Preconditions.checkState( + env.valuesMissing(), "Not done dep should never have been enqueued"); + } + return null; + } + return expectedValue; }); assertThat(tester.evalAndGet(/*keepGoing=*/ false, restartingKey)).isEqualTo(expectedValue); assertThat(numInconsistencyCalls.get()).isEqualTo(2); @@ -2709,21 +2660,18 @@ final SkyKey leaf4 = GraphTester.toSkyKey("leaf4"); final AtomicBoolean shouldNotBuildLeaf4 = new AtomicBoolean(false); injectGraphListenerForTesting( - new Listener() { - @Override - public void accept(SkyKey key, EventType type, Order order, Object context) { - if (shouldNotBuildLeaf4.get() - && key.equals(leaf4) - && type != EventType.REMOVE_REVERSE_DEP - && type != EventType.GET_BATCH) { - throw new IllegalStateException( - "leaf4 should not have been considered this build: " - + type - + ", " - + order - + ", " - + context); - } + (key, type, order, context) -> { + if (shouldNotBuildLeaf4.get() + && key.equals(leaf4) + && type != EventType.REMOVE_REVERSE_DEP + && type != EventType.GET_BATCH) { + throw new IllegalStateException( + "leaf4 should not have been considered this build: " + + type + + ", " + + order + + ", " + + context); } }, /*deterministic=*/ false); @@ -2746,31 +2694,26 @@ tester .getOrCreate(topKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) - throws SkyFunctionException, InterruptedException { - // Request the first group, [leaf0, leaf1, leaf2]. - // In the first build, it has values ["leaf2", "leaf3", "leaf4"]. - // In the second build it has values ["leaf2", "leaf3", "leaf5"] - Map<SkyKey, SkyValue> values = env.getValues(leaves); - if (env.valuesMissing()) { - return null; - } - - // Request the second group. In the first build it's [leaf2, leaf4]. - // In the second build it's [leaf2, leaf5] - env.getValues( - ImmutableList.of( - leaves.get(2), - GraphTester.toSkyKey( - ((StringValue) values.get(leaves.get(2))).getValue()))); - if (env.valuesMissing()) { - return null; - } - - return topValue; + (skyKey, env) -> { + // Request the first group, [leaf0, leaf1, leaf2]. + // In the first build, it has values ["leaf2", "leaf3", "leaf4"]. + // In the second build it has values ["leaf2", "leaf3", "leaf5"] + Map<SkyKey, SkyValue> values = env.getValues(leaves); + if (env.valuesMissing()) { + return null; } + + // Request the second group. In the first build it's [leaf2, leaf4]. + // In the second build it's [leaf2, leaf5] + env.getValues( + ImmutableList.of( + leaves.get(2), + GraphTester.toSkyKey(((StringValue) values.get(leaves.get(2))).getValue()))); + if (env.valuesMissing()) { + return null; + } + + return topValue; }); // First build: assert we can evaluate "top". @@ -2825,38 +2768,35 @@ // to see if it is changed, and if it is dirty. final CountDownLatch threadsStarted = new CountDownLatch(3); injectGraphListenerForTesting( - new Listener() { - @Override - public void accept(SkyKey key, EventType type, Order order, Object context) { - if (!blockingEnabled.get()) { - return; - } - if (!key.equals(parent)) { - return; - } - if (type == EventType.IS_CHANGED && order == Order.BEFORE) { - threadsStarted.countDown(); - } - // Dirtiness only checked by dirty thread. - if (type == EventType.IS_DIRTY && order == Order.BEFORE) { - threadsStarted.countDown(); - } - if (type == EventType.MARK_DIRTY) { - TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( - threadsStarted, "Both threads did not query if value isChanged in time"); - if (order == Order.BEFORE) { - DirtyType dirtyType = (DirtyType) context; - if (dirtyType.equals(DirtyType.DIRTY)) { - TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( - waitForChanged, "'changed' thread did not mark value changed in time"); - return; - } + (key, type, order, context) -> { + if (!blockingEnabled.get()) { + return; + } + if (!key.equals(parent)) { + return; + } + if (type == EventType.IS_CHANGED && order == Order.BEFORE) { + threadsStarted.countDown(); + } + // Dirtiness only checked by dirty thread. + if (type == EventType.IS_DIRTY && order == Order.BEFORE) { + threadsStarted.countDown(); + } + if (type == EventType.MARK_DIRTY) { + TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( + threadsStarted, "Both threads did not query if value isChanged in time"); + if (order == Order.BEFORE) { + DirtyType dirtyType = (DirtyType) context; + if (dirtyType.equals(DirtyType.DIRTY)) { + TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( + waitForChanged, "'changed' thread did not mark value changed in time"); + return; } - if (order == Order.AFTER) { - DirtyType dirtyType = ((NotifyingHelper.MarkDirtyAfterContext) context).dirtyType(); - if (dirtyType.equals(DirtyType.CHANGE)) { - waitForChanged.countDown(); - } + } + if (order == Order.AFTER) { + DirtyType dirtyType = ((NotifyingHelper.MarkDirtyAfterContext) context).dirtyType(); + if (dirtyType.equals(DirtyType.CHANGE)) { + waitForChanged.countDown(); } } } @@ -3108,18 +3048,14 @@ tester .getOrCreate(leafKey, /*markAsModified=*/ true) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) - throws InterruptedException { - notifyStart.countDown(); - if (shouldSleep.get()) { - // Should be interrupted within 5 seconds. - Thread.sleep(5000); - throw new AssertionError("leaf was not interrupted"); - } - return new StringValue("crunchy"); + (skyKey, env) -> { + notifyStart.countDown(); + if (shouldSleep.get()) { + // Should be interrupted within 5 seconds. + Thread.sleep(5000); + throw new AssertionError("leaf was not interrupted"); } + return new StringValue("crunchy"); }); tester.invalidate(); TestThread evalThread = @@ -3289,12 +3225,9 @@ tester .getOrCreate(top) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException { - topEvaluated.set(true); - return env.getValue(leaf) == null ? null : fixedTopValue; - } + (skyKey, env) -> { + topEvaluated.set(true); + return env.getValue(leaf) == null ? null : fixedTopValue; }); // And top is evaluated, StringValue topValue = (StringValue) tester.evalAndGet("top"); @@ -3337,15 +3270,12 @@ tester .getOrCreate(top) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException { - topEvaluated.set(true); + (skyKey, env) -> { + topEvaluated.set(true); - return env.getValue(other) == null || env.getValue(leaf) == null - ? null - : fixedTopValue; - } + return env.getValue(other) == null || env.getValue(leaf) == null + ? null + : fixedTopValue; }); // And top is evaluated, StringValue topValue = (StringValue) tester.evalAndGet("top"); @@ -3379,27 +3309,23 @@ public void changedChildChangesDepOfParent() throws Exception { SkyKey buildFile = GraphTester.nonHermeticKey("buildFile"); ValueComputer authorDrink = - new ValueComputer() { - @Override - public SkyValue compute(Map<SkyKey, SkyValue> deps, SkyFunction.Environment env) - throws InterruptedException { - String author = ((StringValue) deps.get(buildFile)).getValue(); - StringValue beverage; - switch (author) { - case "hemingway": - beverage = (StringValue) env.getValue(GraphTester.toSkyKey("absinthe")); - break; - case "joyce": - beverage = (StringValue) env.getValue(GraphTester.toSkyKey("whiskey")); - break; - default: - throw new IllegalStateException(author); - } - if (beverage == null) { - return null; - } - return new StringValue(author + " drank " + beverage.getValue()); + (deps, env) -> { + String author = ((StringValue) deps.get(buildFile)).getValue(); + StringValue beverage; + switch (author) { + case "hemingway": + beverage = (StringValue) env.getValue(GraphTester.toSkyKey("absinthe")); + break; + case "joyce": + beverage = (StringValue) env.getValue(GraphTester.toSkyKey("whiskey")); + break; + default: + throw new IllegalStateException(author); } + if (beverage == null) { + return null; + } + return new StringValue(author + " drank " + beverage.getValue()); }; tester.set(buildFile, new StringValue("hemingway")); @@ -3456,13 +3382,8 @@ } private static final SkyFunction INTERRUPT_BUILDER = - new SkyFunction() { - - @Override - public SkyValue compute(SkyKey skyKey, Environment env) - throws SkyFunctionException, InterruptedException { - throw new InterruptedException(); - } + (skyKey, env) -> { + throw new InterruptedException(); }; /** @@ -3661,15 +3582,11 @@ tester.getOrCreate(error).setHasTransientError(true); SkyKey topKey = GraphTester.toSkyKey("top"); SkyFunction errorFunction = - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) - throws GenericFunctionException, InterruptedException { - try { - return env.getValueOrThrow(error, SomeErrorException.class); - } catch (SomeErrorException e) { - throw new GenericFunctionException(e, Transience.PERSISTENT); - } + (skyKey, env) -> { + try { + return env.getValueOrThrow(error, SomeErrorException.class); + } catch (SomeErrorException e) { + throw new GenericFunctionException(e, Transience.PERSISTENT); } }; tester.getOrCreate(topKey).setBuilder(errorFunction); @@ -3770,17 +3687,13 @@ tester.getOrCreate(error).setHasError(true); SkyKey topKey = GraphTester.toSkyKey("top"); SkyFunction recoveryErrorFunction = - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) - throws SkyFunctionException, InterruptedException { - try { - env.getValueOrThrow(error, SomeErrorException.class); - } catch (SomeErrorException e) { - throw new GenericFunctionException(e, Transience.PERSISTENT); - } - return null; + (skyKey, env) -> { + try { + env.getValueOrThrow(error, SomeErrorException.class); + } catch (SomeErrorException e) { + throw new GenericFunctionException(e, Transience.PERSISTENT); } + return null; }; tester.getOrCreate(topKey).setBuilder(recoveryErrorFunction); EvaluationResult<StringValue> result = tester.eval(/*keepGoing=*/ false, topKey); @@ -3853,30 +3766,26 @@ final CountDownLatch otherThreadWinning = new CountDownLatch(1); final AtomicReference<Thread> firstThread = new AtomicReference<>(); injectGraphListenerForTesting( - new Listener() { - @Override - public void accept(SkyKey key, EventType type, Order order, Object context) { - if (!waitForSecondCall.get()) { + (key, type, order, context) -> { + if (!waitForSecondCall.get()) { + return; + } + if (key.equals(midKey)) { + if (type == EventType.CREATE_IF_ABSENT) { + // The first thread to create midKey will not be the first thread to add a reverse dep + // to it. + firstThread.compareAndSet(null, Thread.currentThread()); return; } - if (key.equals(midKey)) { - if (type == EventType.CREATE_IF_ABSENT) { - // The first thread to create midKey will not be the first thread to add a - // reverse dep to it. - firstThread.compareAndSet(null, Thread.currentThread()); - return; - } - if (type == EventType.ADD_REVERSE_DEP) { - if (order == Order.BEFORE && Thread.currentThread().equals(firstThread.get())) { - // If this thread created midKey, block until the other thread adds a dep on - // it. - TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( - otherThreadWinning, "other thread didn't pass this one"); - } else if (order == Order.AFTER - && !Thread.currentThread().equals(firstThread.get())) { - // This thread has added a dep. Allow the other thread to proceed. - otherThreadWinning.countDown(); - } + if (type == EventType.ADD_REVERSE_DEP) { + if (order == Order.BEFORE && Thread.currentThread().equals(firstThread.get())) { + // If this thread created midKey, block until the other thread adds a dep on it. + TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( + otherThreadWinning, "other thread didn't pass this one"); + } else if (order == Order.AFTER + && !Thread.currentThread().equals(firstThread.get())) { + // This thread has added a dep. Allow the other thread to proceed. + otherThreadWinning.countDown(); } } } @@ -3934,58 +3843,48 @@ tester .getOrCreate(errorKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException { - // Given that errorKey waits for otherErrorKey to begin evaluation before completing - // its evaluation, - TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( - otherStarted, "otherErrorKey's SkyFunction didn't start in time."); - // And given that errorKey throws an error, - throw new GenericFunctionException( - new SomeErrorException("error"), Transience.PERSISTENT); - } + (skyKey, env) -> { + // Given that errorKey waits for otherErrorKey to begin evaluation before completing + // its evaluation, + TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( + otherStarted, "otherErrorKey's SkyFunction didn't start in time."); + // And given that errorKey throws an error, + throw new GenericFunctionException( + new SomeErrorException("error"), Transience.PERSISTENT); }); tester .getOrCreate(otherErrorKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) - throws SkyFunctionException, InterruptedException { - otherStarted.countDown(); - int invocations = numOtherInvocations.incrementAndGet(); - // And given that otherErrorKey waits for errorKey's error to be committed before - // trying to get errorKey's value, - TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( - errorCommitted, "errorKey's error didn't get committed to the graph in time"); - try { - SkyValue value = env.getValueOrThrow(errorKey, SomeErrorException.class); - if (value != null) { - nonNullValueMessage.set("bogus non-null value " + value); - } - if (invocations != 1) { - bogusInvocationMessage.set("bogus invocation count: " + invocations); - } - otherDone.countDown(); - // And given that otherErrorKey throws an error, - throw new GenericFunctionException( - new SomeErrorException("other"), Transience.PERSISTENT); - } catch (SomeErrorException e) { - fail(); - return null; + (skyKey, env) -> { + otherStarted.countDown(); + int invocations = numOtherInvocations.incrementAndGet(); + // And given that otherErrorKey waits for errorKey's error to be committed before + // trying to get errorKey's value, + TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( + errorCommitted, "errorKey's error didn't get committed to the graph in time"); + try { + SkyValue value = env.getValueOrThrow(errorKey, SomeErrorException.class); + if (value != null) { + nonNullValueMessage.set("bogus non-null value " + value); } + if (invocations != 1) { + bogusInvocationMessage.set("bogus invocation count: " + invocations); + } + otherDone.countDown(); + // And given that otherErrorKey throws an error, + throw new GenericFunctionException( + new SomeErrorException("other"), Transience.PERSISTENT); + } catch (SomeErrorException e) { + fail(); + return null; } }); injectGraphListenerForTesting( - new Listener() { - @Override - public void accept(SkyKey key, EventType type, Order order, Object context) { - if (key.equals(errorKey) && type == EventType.SET_VALUE && order == Order.AFTER) { - errorCommitted.countDown(); - TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( - otherDone, "otherErrorKey's SkyFunction didn't finish in time."); - } + (key, type, order, context) -> { + if (key.equals(errorKey) && type == EventType.SET_VALUE && order == Order.AFTER) { + errorCommitted.countDown(); + TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( + otherDone, "otherErrorKey's SkyFunction didn't finish in time."); } }, /*deterministic=*/ false); @@ -4138,16 +4037,13 @@ tester .getOrCreate(wait) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException { - // Wait for the parent and child actions to complete before computing wait node - parentEvaluated.await(TestUtils.WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS); - assertThatEvents(eventCollector).containsExactly(childEvent, parentEvent); + (skyKey, env) -> { + // Wait for the parent and child actions to complete before computing wait node + parentEvaluated.await(TestUtils.WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS); + assertThatEvents(eventCollector).containsExactly(childEvent, parentEvent); - env.getListener().handle(Event.progress(waitEvent)); - return waitStringValue; - } + env.getListener().handle(Event.progress(waitEvent)); + return waitStringValue; }); tester .getOrCreate(child) @@ -4773,18 +4669,15 @@ tester .getOrCreate(waitForShutdownKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException { - shutdownAwaiterStarted.countDown(); - TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( - ((SkyFunctionEnvironment) env).getExceptionLatchForTesting(), - "exception not thrown"); - // Threadpool is shutting down. Don't try to synchronize anything in the future - // during error bubbling. - synchronizeThreads.set(false); - throw new InterruptedException(); - } + (skyKey, env) -> { + shutdownAwaiterStarted.countDown(); + TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( + ((SkyFunctionEnvironment) env).getExceptionLatchForTesting(), + "exception not thrown"); + // Threadpool is shutting down. Don't try to synchronize anything in the future + // during error bubbling. + synchronizeThreads.set(false); + throw new InterruptedException(); }); EvaluationResult<StringValue> result = tester.eval(/*keepGoing=*/ false, cachedParentKey, uncachedParentKey, waitForShutdownKey); @@ -4823,23 +4716,20 @@ final CountDownLatch topRequestedError = new CountDownLatch(1); final CountDownLatch errorMarkedClean = new CountDownLatch(1); injectGraphListenerForTesting( - new Listener() { - @Override - public void accept(SkyKey key, EventType type, Order order, Object context) { - if (errorKey.equals(key) && type == EventType.MARK_CLEAN) { - if (order == Order.BEFORE) { - TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( - topRequestedError, "top didn't request"); - } else { - errorMarkedClean.countDown(); - TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( - topSecondEval, "top didn't restart"); - // Make sure that the other thread notices the error and interrupts this thread. - try { - Thread.sleep(TestUtils.WAIT_TIMEOUT_MILLISECONDS); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } + (key, type, order, context) -> { + if (errorKey.equals(key) && type == EventType.MARK_CLEAN) { + if (order == Order.BEFORE) { + TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( + topRequestedError, "top didn't request"); + } else { + errorMarkedClean.countDown(); + TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( + topSecondEval, "top didn't restart"); + // Make sure that the other thread notices the error and interrupts this thread. + try { + Thread.sleep(TestUtils.WAIT_TIMEOUT_MILLISECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); } } } @@ -4889,16 +4779,13 @@ SkyKey errorKey = GraphTester.nonHermeticKey("error"); final SkyKey otherKey = GraphTester.toSkyKey("other"); SkyFunction parentBuilder = - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException { - env.getValue(errorKey); - env.getValue(otherKey); - if (env.valuesMissing()) { - return null; - } - return new StringValue("parent"); + (skyKey, env) -> { + env.getValue(errorKey); + env.getValue(otherKey); + if (env.valuesMissing()) { + return null; } + return new StringValue("parent"); }; tester.getOrCreate(parent1Key).setBuilder(parentBuilder); tester.getOrCreate(parent2Key).setBuilder(parentBuilder); @@ -5058,21 +4945,18 @@ Thread mainThread = Thread.currentThread(); AtomicBoolean shouldInterrupt = new AtomicBoolean(false); injectGraphListenerForTesting( - new Listener() { - @Override - public void accept(SkyKey key, EventType type, Order order, Object context) { - if (shouldInterrupt.get() - && key.equals(topKey) - && type == EventType.IS_READY - && order == Order.BEFORE) { - mainThread.interrupt(); - shouldInterrupt.set(false); - try { - // Make sure threadpool propagates interrupt. - Thread.sleep(TestUtils.WAIT_TIMEOUT_MILLISECONDS); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } + (key, type, order, context) -> { + if (shouldInterrupt.get() + && key.equals(topKey) + && type == EventType.IS_READY + && order == Order.BEFORE) { + mainThread.interrupt(); + shouldInterrupt.set(false); + try { + // Make sure threadpool propagates interrupt. + Thread.sleep(TestUtils.WAIT_TIMEOUT_MILLISECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); } } },
diff --git a/src/test/java/com/google/devtools/build/skyframe/ParallelEvaluatorTest.java b/src/test/java/com/google/devtools/build/skyframe/ParallelEvaluatorTest.java index 76e6672..56b4e31 100644 --- a/src/test/java/com/google/devtools/build/skyframe/ParallelEvaluatorTest.java +++ b/src/test/java/com/google/devtools/build/skyframe/ParallelEvaluatorTest.java
@@ -40,7 +40,6 @@ import com.google.devtools.build.lib.concurrent.AbstractQueueVisitor; import com.google.devtools.build.lib.concurrent.BlazeInterners; import com.google.devtools.build.lib.events.Event; -import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.events.EventKind; import com.google.devtools.build.lib.events.ExtendedEventHandler; import com.google.devtools.build.lib.events.ExtendedEventHandler.Postable; @@ -50,7 +49,6 @@ import com.google.devtools.build.lib.testutil.TestUtils; import com.google.devtools.build.skyframe.GraphTester.StringValue; import com.google.devtools.build.skyframe.NotifyingHelper.EventType; -import com.google.devtools.build.skyframe.NotifyingHelper.Listener; import com.google.devtools.build.skyframe.NotifyingHelper.Order; import com.google.devtools.build.skyframe.SkyFunctionException.Transience; import com.google.testing.junit.testparameterinjector.TestParameter; @@ -172,18 +170,15 @@ tester .getOrCreate(parentKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException { - SettableFuture<SkyValue> future = SettableFuture.create(); - future.set(new StringValue("good")); - env.dependOnFuture(future); - assertThat(env.valuesMissing()).isFalse(); - try { - return future.get(); - } catch (ExecutionException e) { - throw new RuntimeException(e); - } + (skyKey, env) -> { + SettableFuture<SkyValue> future = SettableFuture.create(); + future.set(new StringValue("good")); + env.dependOnFuture(future); + assertThat(env.valuesMissing()).isFalse(); + try { + return future.get(); + } catch (ExecutionException e) { + throw new RuntimeException(e); } }); graph = new InMemoryGraphImpl(); @@ -226,14 +221,11 @@ }); graph = NotifyingHelper.makeNotifyingTransformer( - new Listener() { - @Override - public void accept(SkyKey key, EventType type, Order order, Object context) { - // NodeEntry.addExternalDep is called as part of bookkeeping at the end of - // AbstractParallelEvaluator.Evaluate#run. - if (key == parentKey && type == EventType.ADD_EXTERNAL_DEP) { - doneLatch.countDown(); - } + (key, type, order, context) -> { + // NodeEntry.addExternalDep is called as part of bookkeeping at the end of + // AbstractParallelEvaluator.Evaluate#run. + if (key == parentKey && type == EventType.ADD_EXTERNAL_DEP) { + doneLatch.countDown(); } }) .transform(new InMemoryGraphImpl()); @@ -286,12 +278,9 @@ }); graph = NotifyingHelper.makeNotifyingTransformer( - new Listener() { - @Override - public void accept(SkyKey key, EventType type, Order order, Object context) { - if (key == childKey && type == EventType.SET_VALUE) { - doneLatch.countDown(); - } + (key, type, order, context) -> { + if (key == childKey && type == EventType.SET_VALUE) { + doneLatch.countDown(); } }) .transform(new InMemoryGraphImpl()); @@ -305,27 +294,21 @@ */ @Test public void interruptedFunction() throws Exception { - runInterruptionTest(new SkyFunctionFactory() { - @Override - public SkyFunction create(final Semaphore threadStarted, final String[] errorMessage) { - return new SkyFunction() { - @Override - public SkyValue compute(SkyKey key, Environment env) throws InterruptedException { - // Signal the waiting test thread that the evaluator thread has really started. - threadStarted.release(); + runInterruptionTest( + (threadStarted, errorMessage) -> + (key, env) -> { + // Signal the waiting test thread that the evaluator thread has really started. + threadStarted.release(); - // Simulate a SkyFunction that runs for 10 seconds (this number was chosen arbitrarily). - // The main thread should interrupt it shortly after it got started. - Thread.sleep(10 * 1000); + // Simulate a SkyFunction that runs for 10 seconds (this number was chosen + // arbitrarily). The main thread should interrupt it shortly after it got started. + Thread.sleep(10 * 1000); - // Set an error message to indicate that the expected interruption didn't happen. - // We can't use Assert.fail(String) on an async thread. - errorMessage[0] = "SkyFunction should have been interrupted"; - return null; - } - }; - } - }); + // Set an error message to indicate that the expected interruption didn't happen. + // We can't use Assert.fail(String) on an async thread. + errorMessage[0] = "SkyFunction should have been interrupted"; + return null; + }); } /** @@ -338,10 +321,8 @@ @Test public void interruptedEvaluatorThread() throws Exception { runInterruptionTest( - new SkyFunctionFactory() { - @Override - public SkyFunction create(final Semaphore threadStarted, final String[] errorMessage) { - return new SkyFunction() { + (threadStarted, errorMessage) -> + new SkyFunction() { // No need to synchronize access to this field; we always request just one more // dependency, so it's only one SkyFunction running at any time. private int valueIdCounter = 0; @@ -360,9 +341,7 @@ // SkyFunctions. return null; } - }; - } - }); + }); } @Test @@ -406,19 +385,19 @@ }; // And A's SkyFunction tries to observe an interrupt after it starts computing, AtomicBoolean keyAComputeInterrupted = new AtomicBoolean(false); - tester.getOrCreate(keyA).setBuilder(new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException { - keyAStartedComputingLatch.countDown(); - try { - Thread.sleep(TestUtils.WAIT_TIMEOUT_MILLISECONDS); - throw new IllegalStateException("shouldn't get here"); - } catch (InterruptedException e) { - keyAComputeInterrupted.set(true); - throw e; - } - } - }); + tester + .getOrCreate(keyA) + .setBuilder( + (skyKey, env) -> { + keyAStartedComputingLatch.countDown(); + try { + Thread.sleep(TestUtils.WAIT_TIMEOUT_MILLISECONDS); + throw new IllegalStateException("shouldn't get here"); + } catch (InterruptedException e) { + keyAComputeInterrupted.set(true); + throw e; + } + }); // And we have a dedicated thread that kicks off the evaluation of A and B together (in that // order). @@ -453,14 +432,14 @@ final SkyKey waitKey = GraphTester.toSkyKey("wait"); final SkyKey fastKey = GraphTester.toSkyKey("fast"); SkyKey leafKey = GraphTester.toSkyKey("leaf"); - tester.getOrCreate(waitKey).setBuilder(new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException { - allValuesReady.countDown(); - Thread.sleep(10000); - throw new AssertionError("Should have been interrupted"); - } - }); + tester + .getOrCreate(waitKey) + .setBuilder( + (skyKey, env) -> { + allValuesReady.countDown(); + Thread.sleep(10000); + throw new AssertionError("Should have been interrupted"); + }); tester.getOrCreate(fastKey).setBuilder(new ChainedFunction(null, null, allValuesReady, false, new StringValue("fast"), ImmutableList.of(leafKey))); tester.set(leafKey, new StringValue("leaf")); @@ -547,23 +526,22 @@ GraphTester.NODE_TYPE, valueBuilderFactory.create(threadStarted, wasError)), false); - Thread t = new Thread(new Runnable() { - @Override - public void run() { - try { - evaluator.eval(ImmutableList.of(GraphTester.toSkyKey("a"))); + Thread t = + new Thread( + () -> { + try { + evaluator.eval(ImmutableList.of(GraphTester.toSkyKey("a"))); - // There's no real need to set an error here. If the thread is not interrupted then - // threadInterrupted is not released and the test thread will fail to acquire it. - wasError[0] = "evaluation should have been interrupted"; - } catch (InterruptedException e) { - // This is the interrupt we are waiting for. It should come straight from the - // evaluator (more precisely, the AbstractQueueVisitor). - // Signal the waiting test thread that the interrupt was acknowledged. - threadInterrupted.release(); - } - } - }); + // There's no real need to set an error here. If the thread is not interrupted then + // threadInterrupted is not released and the test thread will fail to acquire it. + wasError[0] = "evaluation should have been interrupted"; + } catch (InterruptedException e) { + // This is the interrupt we are waiting for. It should come straight from the + // evaluator (more precisely, the AbstractQueueVisitor). + // Signal the waiting test thread that the interrupt was acknowledged. + threadInterrupted.release(); + } + }); // Start the thread and wait for a semaphore. This ensures that the thread was really started. t.start(); @@ -671,15 +649,14 @@ set("a", "a").setWarning("warning on 'a'"); SkyKey a = GraphTester.toSkyKey("a"); SkyKey top = GraphTester.toSkyKey("top"); - tester.getOrCreate(top).setBuilder(new SkyFunction() { - @Override - public SkyValue compute(SkyKey key, Environment env) - throws SkyFunctionException, InterruptedException { - // The event from a should already have been posted. - assertThat(storedEventHandler.getEvents()).hasSize(1); - return new StringValue("foo"); - } - }); + tester + .getOrCreate(top) + .setBuilder( + (key, env) -> { + // The event from a should already have been posted. + assertThat(storedEventHandler.getEvents()).hasSize(1); + return new StringValue("foo"); + }); // Build a so that it is already in the graph. eval(false, a); storedEventHandler.clear(); @@ -696,21 +673,21 @@ SkyKey b = GraphTester.toSkyKey("b"); tester.getOrCreate(b).setHasError(true); Event errorEvent = Event.error("foobar"); - tester.getOrCreate(a).setBuilder(new SkyFunction() { - @Override - public SkyValue compute(SkyKey key, Environment env) - throws SkyFunctionException, InterruptedException { - try { - if (env.getValueOrThrow(b, SomeErrorException.class) == null) { - return null; - } - } catch (SomeErrorException ignored) { - // Continue silently. - } - env.getListener().handle(errorEvent); - throw new SkyFunctionException(new SomeErrorException("bazbar"), Transience.PERSISTENT) {}; - } - }); + tester + .getOrCreate(a) + .setBuilder( + (key, env) -> { + try { + if (env.getValueOrThrow(b, SomeErrorException.class) == null) { + return null; + } + } catch (SomeErrorException ignored) { + // Continue silently. + } + env.getListener().handle(errorEvent); + throw new SkyFunctionException( + new SomeErrorException("bazbar"), Transience.PERSISTENT) {}; + }); eval(false, a); assertThat(storedEventHandler.getEvents()).containsExactly(errorEvent); } @@ -1841,12 +1818,12 @@ graph = new InMemoryGraphImpl(); SkyKey errorKey = GraphTester.toSkyKey("my_error_value"); final SomeOtherErrorException exception = new SomeOtherErrorException("error exception"); - tester.getOrCreate(errorKey).setBuilder(new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException { - throw new SkyFunctionException(exception, Transience.PERSISTENT) {}; - } - }); + tester + .getOrCreate(errorKey) + .setBuilder( + (skyKey, env) -> { + throw new SkyFunctionException(exception, Transience.PERSISTENT) {}; + }); SkyKey topKey = GraphTester.toSkyKey("top"); tester.getOrCreate(topKey).addErrorDependency(errorKey, new StringValue("recovered")) .setComputedValue(CONCATENATE); @@ -1875,34 +1852,30 @@ final SomeErrorException exception = new SomeErrorException("error exception"); final SomeErrorException topException = new SomeErrorException("top exception"); final StringValue topValue = new StringValue("top"); - tester.getOrCreate(errorKey).setBuilder(new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws GenericFunctionException { - throw new GenericFunctionException(exception, Transience.PERSISTENT); - } - }); + tester + .getOrCreate(errorKey) + .setBuilder( + (skyKey, env) -> { + throw new GenericFunctionException(exception, Transience.PERSISTENT); + }); SkyKey topKey = GraphTester.toSkyKey("top"); final SkyKey parentKey = GraphTester.toSkyKey("parent"); tester.getOrCreate(parentKey).addDependency(errorKey).setComputedValue(CONCATENATE); tester .getOrCreate(topKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) - throws GenericFunctionException, InterruptedException { - try { - if (env.getValueOrThrow(parentKey, SomeErrorException.class) == null) { - return null; - } - } catch (SomeErrorException e) { - assertWithMessage(e.toString()).that(e).isEqualTo(exception); + (skyKey, env) -> { + try { + if (env.getValueOrThrow(parentKey, SomeErrorException.class) == null) { + return null; } - if (keepGoing) { - return topValue; - } else { - throw new GenericFunctionException(topException, Transience.PERSISTENT); - } + } catch (SomeErrorException e) { + assertWithMessage(e.toString()).that(e).isEqualTo(exception); + } + if (keepGoing) { + return topValue; + } else { + throw new GenericFunctionException(topException, Transience.PERSISTENT); } }); tester.getOrCreate(topKey).addErrorDependency(errorKey, new StringValue("recovered")) @@ -1946,32 +1919,31 @@ } final SkyKey leaf4 = GraphTester.toSkyKey("leaf4"); tester.set(leaf4, new StringValue("leaf" + 4)); - tester.getOrCreate(topKey).setBuilder(new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException, - InterruptedException { - if (valuesOrThrow) { - env.getValuesOrThrow(leaves, SomeErrorException.class); - } else { - env.getValues(leaves); - } - if (twoCalls && env.valuesMissing()) { - return null; - } - SkyKey first = sameFirst ? leaves.get(0) : leaf4; - SkyKey second = sameFirst ? leaf4 : leaves.get(2); - List<SkyKey> secondRequest = ImmutableList.of(first, second); - if (valuesOrThrow) { - env.getValuesOrThrow(secondRequest, SomeErrorException.class); - } else { - env.getValues(secondRequest); - } - if (env.valuesMissing()) { - return null; - } - return new StringValue("top"); - } - }); + tester + .getOrCreate(topKey) + .setBuilder( + (skyKey, env) -> { + if (valuesOrThrow) { + env.getValuesOrThrow(leaves, SomeErrorException.class); + } else { + env.getValues(leaves); + } + if (twoCalls && env.valuesMissing()) { + return null; + } + SkyKey first = sameFirst ? leaves.get(0) : leaf4; + SkyKey second = sameFirst ? leaf4 : leaves.get(2); + ImmutableList<SkyKey> secondRequest = ImmutableList.of(first, second); + if (valuesOrThrow) { + env.getValuesOrThrow(secondRequest, SomeErrorException.class); + } else { + env.getValues(secondRequest); + } + if (env.valuesMissing()) { + return null; + } + return new StringValue("top"); + }); eval(/*keepGoing=*/false, topKey); assertThat(eval(/*keepGoing=*/false, topKey)).isEqualTo(new StringValue("top")); } @@ -2021,12 +1993,12 @@ SkyKey parentKey = GraphTester.toSkyKey("parent"); final SkyKey errorDep = GraphTester.toSkyKey("errorChild"); final SomeErrorException childExn = new SomeErrorException("child error"); - tester.getOrCreate(errorDep).setBuilder(new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException { - throw new GenericFunctionException(childExn, Transience.PERSISTENT); - } - }); + tester + .getOrCreate(errorDep) + .setBuilder( + (skyKey, env) -> { + throw new GenericFunctionException(childExn, Transience.PERSISTENT); + }); final List<SkyKey> deps = new ArrayList<>(); for (int i = 1; i <= 3; i++) { SkyKey dep = GraphTester.toSkyKey("child" + i); @@ -2037,24 +2009,20 @@ tester .getOrCreate(parentKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) - throws SkyFunctionException, InterruptedException { - try { - SkyValue value = env.getValueOrThrow(errorDep, SomeErrorException.class); - if (value == null) { - return null; - } - } catch (SomeErrorException e) { - // Recover from the child error. - } - env.getValues(deps); - if (env.valuesMissing()) { + (skyKey, env) -> { + try { + SkyValue value = env.getValueOrThrow(errorDep, SomeErrorException.class); + if (value == null) { return null; } - throw new GenericFunctionException(parentExn, Transience.PERSISTENT); + } catch (SomeErrorException e) { + // Recover from the child error. } + env.getValues(deps); + if (env.valuesMissing()) { + return null; + } + throw new GenericFunctionException(parentExn, Transience.PERSISTENT); }); EvaluationResult<StringValue> evaluationResult = eval(keepGoing, ImmutableList.of(parentKey)); assertThat(evaluationResult.hasError()).isTrue(); @@ -2129,11 +2097,8 @@ ExtendedEventHandler reporter = new Reporter( new EventBus(), - new EventHandler() { - @Override - public void handle(Event e) { - throw new IllegalStateException(); - } + e -> { + throw new IllegalStateException(); }); MemoizingEvaluator aug = @@ -2191,46 +2156,41 @@ tester .getOrCreate(parentKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) - throws SkyFunctionException, InterruptedException { - int invocations = numParentInvocations.incrementAndGet(); - if (handleChildError) { - try { - SkyValue value = env.getValueOrThrow(childKey, SomeErrorException.class); - // On the first invocation, either the child error should already be cached and - // not propagated, or it should be computed freshly and not propagated. On the - // second build (error bubbling), the child error should be propagated. - assertWithMessage("bogus non-null value " + value).that(value == null).isTrue(); - assertWithMessage("parent incorrectly re-computed during normal evaluation") - .that(invocations) - .isEqualTo(1); - assertWithMessage("child error not propagated during error bubbling") - .that(env.inErrorBubblingForTesting()) - .isFalse(); - return value; - } catch (SomeErrorException e) { - assertWithMessage("child error propagated during normal evaluation") - .that(env.inErrorBubblingForTesting()) - .isTrue(); - assertThat(invocations).isEqualTo(2); - return null; - } + (skyKey, env) -> { + int invocations = numParentInvocations.incrementAndGet(); + if (handleChildError) { + try { + SkyValue value = env.getValueOrThrow(childKey, SomeErrorException.class); + // On the first invocation, either the child error should already be cached and + // not propagated, or it should be computed freshly and not propagated. On the + // second build (error bubbling), the child error should be propagated. + assertWithMessage("bogus non-null value " + value).that(value == null).isTrue(); + assertWithMessage("parent incorrectly re-computed during normal evaluation") + .that(invocations) + .isEqualTo(1); + assertWithMessage("child error not propagated during error bubbling") + .that(env.inErrorBubblingForTesting()) + .isFalse(); + return value; + } catch (SomeErrorException e) { + assertWithMessage("child error propagated during normal evaluation") + .that(env.inErrorBubblingForTesting()) + .isTrue(); + assertThat(invocations).isEqualTo(2); + return null; + } + } else { + if (invocations == 1) { + assertWithMessage("parent's first computation should be during normal evaluation") + .that(env.inErrorBubblingForTesting()) + .isFalse(); + return env.getValue(childKey); } else { - if (invocations == 1) { - assertWithMessage( - "parent's first computation should be during normal evaluation") - .that(env.inErrorBubblingForTesting()) - .isFalse(); - return env.getValue(childKey); - } else { - assertThat(invocations).isEqualTo(2); - assertWithMessage("parent incorrectly re-computed during normal evaluation") - .that(env.inErrorBubblingForTesting()) - .isTrue(); - return env.getValue(childKey); - } + assertThat(invocations).isEqualTo(2); + assertWithMessage("parent incorrectly re-computed during normal evaluation") + .that(env.inErrorBubblingForTesting()) + .isTrue(); + return env.getValue(childKey); } } }); @@ -2284,64 +2244,52 @@ tester .getOrCreate(otherParentKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException { - int invocations = numOtherParentInvocations.incrementAndGet(); - assertWithMessage("otherParentKey should not be restarted") - .that(invocations) - .isEqualTo(1); - return env.getValue(otherKey); - } + (skyKey, env) -> { + int invocations = numOtherParentInvocations.incrementAndGet(); + assertWithMessage("otherParentKey should not be restarted") + .that(invocations) + .isEqualTo(1); + return env.getValue(otherKey); }); tester .getOrCreate(otherKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException { - otherStarted.countDown(); - TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( - errorCommitted, "error didn't get committed to the graph in time"); - return new StringValue("other"); - } + (skyKey, env) -> { + otherStarted.countDown(); + TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( + errorCommitted, "error didn't get committed to the graph in time"); + return new StringValue("other"); }); tester .getOrCreate(errorKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException { - TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( - otherStarted, "other didn't start in time"); - throw new GenericFunctionException( - new SomeErrorException("error"), Transience.PERSISTENT); - } + (skyKey, env) -> { + TrackingAwaiter.INSTANCE.awaitLatchAndTrackExceptions( + otherStarted, "other didn't start in time"); + throw new GenericFunctionException( + new SomeErrorException("error"), Transience.PERSISTENT); }); tester .getOrCreate(errorParentKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException { - int invocations = numErrorParentInvocations.incrementAndGet(); - try { - SkyValue value = env.getValueOrThrow(errorKey, SomeErrorException.class); - assertWithMessage("bogus non-null value " + value).that(value == null).isTrue(); - if (invocations == 1) { - return null; - } else { - assertThat(env.inErrorBubblingForTesting()).isFalse(); - fail("RACE CONDITION: errorParentKey was restarted!"); - return null; - } - } catch (SomeErrorException e) { - assertWithMessage("child error propagated during normal evaluation") - .that(env.inErrorBubblingForTesting()) - .isTrue(); - assertThat(invocations).isEqualTo(2); + (skyKey, env) -> { + int invocations = numErrorParentInvocations.incrementAndGet(); + try { + SkyValue value = env.getValueOrThrow(errorKey, SomeErrorException.class); + assertWithMessage("bogus non-null value " + value).that(value == null).isTrue(); + if (invocations == 1) { + return null; + } else { + assertThat(env.inErrorBubblingForTesting()).isFalse(); + fail("RACE CONDITION: errorParentKey was restarted!"); return null; } + } catch (SomeErrorException e) { + assertWithMessage("child error propagated during normal evaluation") + .that(env.inErrorBubblingForTesting()) + .isTrue(); + assertThat(invocations).isEqualTo(2); + return null; } }); graph = @@ -2398,15 +2346,15 @@ EvaluationResult<StringValue> result = eval(/*keepGoing=*/true, ImmutableList.of(errorKey)); assertThatEvaluationResult(result).hasSingletonErrorThat(errorKey); SkyKey rogueKey = GraphTester.toSkyKey("rogue"); - tester.getOrCreate(rogueKey).setBuilder(new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) { - // This SkyFunction could do an arbitrarily bad computation, e.g. loop-forever. So we want - // to make sure that it is never run when we want to fail-fast anyway. - fail("eval call should have already terminated"); - return null; - } - }); + tester + .getOrCreate(rogueKey) + .setBuilder( + (skyKey, env) -> { + // This SkyFunction could do an arbitrarily bad computation, e.g. loop-forever. So we + // want to make sure that it is never run when we want to fail-fast anyway. + fail("eval call should have already terminated"); + return null; + }); result = eval(/*keepGoing=*/false, ImmutableList.of(errorKey, rogueKey)); assertThatEvaluationResult(result).hasErrorMapThat().hasSize(1); assertThatEvaluationResult(result).hasErrorEntryForKeyThat(errorKey); @@ -2436,23 +2384,20 @@ tester .getOrCreate(parentKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException { - switch (numComputes.incrementAndGet()) { - case 1: - env.getValue(child1Key); - Preconditions.checkState(env.valuesMissing()); - return null; - case 2: - env.getValue(child2Key); - Preconditions.checkState(env.valuesMissing()); - return null; - case 3: - return new StringValue("the third time's the charm!"); - default: - throw new IllegalStateException(); - } + (skyKey, env) -> { + switch (numComputes.incrementAndGet()) { + case 1: + env.getValue(child1Key); + Preconditions.checkState(env.valuesMissing()); + return null; + case 2: + env.getValue(child2Key); + Preconditions.checkState(env.valuesMissing()); + return null; + case 3: + return new StringValue("the third time's the charm!"); + default: + throw new IllegalStateException(); } }); EvaluationResult<StringValue> result = eval(/*keepGoing=*/ false, ImmutableList.of(parentKey)); @@ -2473,34 +2418,26 @@ tester .getOrCreate(grandparentKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) - throws SkyFunctionException, InterruptedException { - try { - return env.getValueOrThrow(parentKey, SomeErrorException.class); - } catch (SomeErrorException e) { - errorPropagated.set(true); - throw new GenericFunctionException(e, Transience.PERSISTENT); - } + (skyKey, env) -> { + try { + return env.getValueOrThrow(parentKey, SomeErrorException.class); + } catch (SomeErrorException e) { + errorPropagated.set(true); + throw new GenericFunctionException(e, Transience.PERSISTENT); } }); tester .getOrCreate(parentKey) .setBuilder( - new SkyFunction() { - @Override - public SkyValue compute(SkyKey skyKey, Environment env) - throws SkyFunctionException, InterruptedException { - if (explicitlyPropagateError) { - try { - return env.getValueOrThrow(childKey, SomeErrorException.class); - } catch (SomeErrorException e) { - throw new GenericFunctionException(e); - } - } else { - return env.getValue(childKey); + (skyKey, env) -> { + if (explicitlyPropagateError) { + try { + return env.getValueOrThrow(childKey, SomeErrorException.class); + } catch (SomeErrorException e) { + throw new GenericFunctionException(e); } + } else { + return env.getValue(childKey); } }); tester.getOrCreate(childKey).setHasError(/*hasError=*/true);