diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctionEnvironmentForTesting.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctionEnvironmentForTesting.java index d3f523b75cf37c..801603c3c3ce23 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctionEnvironmentForTesting.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctionEnvironmentForTesting.java @@ -50,6 +50,12 @@ public final class SkyFunctionEnvironmentForTesting extends AbstractSkyFunctionE this.skyframeExecutor = skyframeExecutor; } + @Override + protected ValueOrUntypedException getSingleValueOrUntypedException(SkyKey depKey) + throws InterruptedException { + return getOrderedValueOrUntypedExceptions(ImmutableList.of(depKey)).get(0); + } + @Override protected Map getValueOrUntypedExceptions( Iterable depKeys) { diff --git a/src/main/java/com/google/devtools/build/skyframe/AbstractSkyFunctionEnvironment.java b/src/main/java/com/google/devtools/build/skyframe/AbstractSkyFunctionEnvironment.java index 6bf9bda2db04a5..37ce3dfd038c6c 100644 --- a/src/main/java/com/google/devtools/build/skyframe/AbstractSkyFunctionEnvironment.java +++ b/src/main/java/com/google/devtools/build/skyframe/AbstractSkyFunctionEnvironment.java @@ -14,7 +14,6 @@ package com.google.devtools.build.skyframe; import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.ListenableFuture; import com.google.devtools.build.lib.util.GroupedList; import java.util.ArrayList; @@ -40,11 +39,11 @@ public abstract class AbstractSkyFunctionEnvironment implements SkyFunction.Envi @Nullable private final GroupedList temporaryDirectDeps; @Nullable protected List> externalDeps; - public AbstractSkyFunctionEnvironment(@Nullable GroupedList temporaryDirectDeps) { + protected AbstractSkyFunctionEnvironment(@Nullable GroupedList temporaryDirectDeps) { this.temporaryDirectDeps = temporaryDirectDeps; } - public AbstractSkyFunctionEnvironment() { + protected AbstractSkyFunctionEnvironment() { this(null); } @@ -53,31 +52,47 @@ public GroupedList getTemporaryDirectDeps() { return temporaryDirectDeps; } - /** Implementations should set {@link #valuesMissing} as necessary. */ + /** + * Gets a single value or exception. + * + *

Implementations should set {@link #valuesMissing} as necessary. + */ + protected abstract ValueOrUntypedException getSingleValueOrUntypedException(SkyKey depKey) + throws InterruptedException; + + /** + * Gets a map of values or exceptions. + * + *

Implementations should set {@link #valuesMissing} as necessary. + */ protected abstract Map getValueOrUntypedExceptions( Iterable depKeys) throws InterruptedException; - /** Implementations should set {@link #valuesMissing} as necessary. */ + /** + * Gets a list of values or exceptions parallel to the given keys. + * + *

Implementations should set {@link #valuesMissing} as necessary. + */ protected abstract List getOrderedValueOrUntypedExceptions( Iterable depKeys) throws InterruptedException; @Override @Nullable - public SkyValue getValue(SkyKey depKey) throws InterruptedException { + public final SkyValue getValue(SkyKey depKey) throws InterruptedException { return getValueOrThrowHelper(depKey, null, null, null, null); } @Override @Nullable - public SkyValue getValueOrThrow(SkyKey depKey, Class exceptionClass) - throws E, InterruptedException { + public final SkyValue getValueOrThrow( + SkyKey depKey, Class exceptionClass) throws E, InterruptedException { SkyFunctionException.validateExceptionType(exceptionClass); return getValueOrThrowHelper(depKey, exceptionClass, null, null, null); } @Override @Nullable - public SkyValue getValueOrThrow( + public final SkyValue getValueOrThrow( SkyKey depKey, Class exceptionClass1, Class exceptionClass2) throws E1, E2, InterruptedException { SkyFunctionException.validateExceptionType(exceptionClass1); @@ -87,7 +102,7 @@ public SkyValue getValueOrThrow( @Override @Nullable - public + public final SkyValue getValueOrThrow( SkyKey depKey, Class exceptionClass1, @@ -102,7 +117,8 @@ SkyValue getValueOrThrow( @Override @Nullable - public + public final < + E1 extends Exception, E2 extends Exception, E3 extends Exception, E4 extends Exception> SkyValue getValueOrThrow( SkyKey depKey, Class exceptionClass1, @@ -127,28 +143,48 @@ SkyValue getValueOrThrowHelper( @Nullable Class exceptionClass3, @Nullable Class exceptionClass4) throws E1, E2, E3, E4, InterruptedException { - SkyframeIterableResult result = getOrderedValuesAndExceptions(ImmutableSet.of(depKey)); - return result.nextOrThrow(exceptionClass1, exceptionClass2, exceptionClass3, exceptionClass4); + ValueOrUntypedException voe = getSingleValueOrUntypedException(depKey); + SkyValue value = voe.getValue(); + if (value != null) { + return value; + } + Exception e = voe.getException(); + if (e != null) { + if (exceptionClass1 != null && exceptionClass1.isInstance(e)) { + throw exceptionClass1.cast(e); + } + if (exceptionClass2 != null && exceptionClass2.isInstance(e)) { + throw exceptionClass2.cast(e); + } + if (exceptionClass3 != null && exceptionClass3.isInstance(e)) { + throw exceptionClass3.cast(e); + } + if (exceptionClass4 != null && exceptionClass4.isInstance(e)) { + throw exceptionClass4.cast(e); + } + } + valuesMissing = true; + return null; } @Override - public SkyframeLookupResult getValuesAndExceptions(Iterable depKeys) + public final SkyframeLookupResult getValuesAndExceptions(Iterable depKeys) throws InterruptedException { Map valuesOrExceptions = getValueOrUntypedExceptions(depKeys); return new SkyframeLookupResult(() -> valuesMissing = true, valuesOrExceptions::get); } @Override - public SkyframeIterableResult getOrderedValuesAndExceptions(Iterable depKeys) - throws InterruptedException { + public final SkyframeIterableResult getOrderedValuesAndExceptions( + Iterable depKeys) throws InterruptedException { List valuesOrExceptions = getOrderedValueOrUntypedExceptions(depKeys); Iterator valuesOrExceptionsi = valuesOrExceptions.iterator(); return new SkyframeIterableResult(() -> valuesMissing = true, valuesOrExceptionsi); } @Override - public boolean valuesMissing() { - return valuesMissing || (externalDeps != null); + public final boolean valuesMissing() { + return valuesMissing || externalDeps != null; } @Override diff --git a/src/main/java/com/google/devtools/build/skyframe/SkyFunctionEnvironment.java b/src/main/java/com/google/devtools/build/skyframe/SkyFunctionEnvironment.java index 7e2172bc64788d..31b81fd5553d06 100644 --- a/src/main/java/com/google/devtools/build/skyframe/SkyFunctionEnvironment.java +++ b/src/main/java/com/google/devtools/build/skyframe/SkyFunctionEnvironment.java @@ -428,6 +428,30 @@ private static SkyValue getValueOrNullMarker(@Nullable NodeEntry nodeEntry) return valueMaybeWithMetadata; } + @Override + protected ValueOrUntypedException getSingleValueOrUntypedException(SkyKey depKey) + throws InterruptedException { + checkActive(); + checkState( + !depKey.equals(ErrorTransienceValue.KEY), + "Error transience key cannot be in requested deps of %s", + skyKey); + SkyValue depValue = maybeGetValueFromErrorOrDeps(depKey); + if (depValue == null) { + NodeEntry depEntry = evaluatorContext.getGraph().get(skyKey, Reason.DEP_REQUESTED, depKey); + depValue = getValueOrNullMarker(depEntry); + newlyRequestedDepsValues.put(depKey, depValue); + if (depValue != NULL_MARKER) { + maybeUpdateMaxTransitiveSourceVersion(depEntry); + } + } + if (!previouslyRequestedDepsValues.containsKey(depKey)) { + newlyRequestedDeps.add(depKey); + } + processDepValue(depKey, depValue); + return transformToValueOrUntypedException(depValue); + } + @Override protected Map getValueOrUntypedExceptions( Iterable depKeys) throws InterruptedException { diff --git a/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java b/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java index 2b248e326fd15e..ba0bee07b319b7 100644 --- a/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java +++ b/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java @@ -333,6 +333,12 @@ private BlockingSkyFunctionEnvironment( this.eventHandler = eventHandler; } + @Override + protected ValueOrUntypedException getSingleValueOrUntypedException(SkyKey depKey) + throws InterruptedException { + return getOrderedValueOrUntypedExceptions(ImmutableList.of(depKey)).get(0); + } + @Override protected Map getValueOrUntypedExceptions( Iterable depKeys) {