Search in sources :

Example 6 with ValueOrException2

use of com.google.devtools.build.skyframe.ValueOrException2 in project bazel by bazelbuild.

the class ConfiguredTargetFunction method resolveAspectDependencies.

/**
   * Given a list of {@link Dependency} objects, returns a multimap from the {@link SkyKey} of the
   * dependency to the {@link ConfiguredAspect} instances that should be merged into it.
   *
   * <p>Returns null if the required aspects are not computed yet.
   */
@Nullable
private static OrderedSetMultimap<SkyKey, ConfiguredAspect> resolveAspectDependencies(Environment env, Map<SkyKey, ConfiguredTarget> configuredTargetMap, Iterable<Dependency> deps, NestedSetBuilder<Package> transitivePackages) throws AspectCreationException, InterruptedException {
    OrderedSetMultimap<SkyKey, ConfiguredAspect> result = OrderedSetMultimap.create();
    Set<SkyKey> allAspectKeys = new HashSet<>();
    for (Dependency dep : deps) {
        allAspectKeys.addAll(getAspectKeys(dep).values());
    }
    Map<SkyKey, ValueOrException2<AspectCreationException, NoSuchThingException>> depAspects = env.getValuesOrThrow(allAspectKeys, AspectCreationException.class, NoSuchThingException.class);
    for (Dependency dep : deps) {
        SkyKey depKey = TO_KEYS.apply(dep);
        // twice.
        if (result.containsKey(depKey)) {
            continue;
        }
        Map<AspectDescriptor, SkyKey> aspectToKeys = getAspectKeys(dep);
        ConfiguredTarget depConfiguredTarget = configuredTargetMap.get(depKey);
        for (AspectDeps depAspect : dep.getAspects().getVisibleAspects()) {
            SkyKey aspectKey = aspectToKeys.get(depAspect.getAspect());
            AspectValue aspectValue;
            try {
                // TODO(ulfjack): Catch all thrown AspectCreationException and NoSuchThingException
                // instances and merge them into a single Exception to get full root cause data.
                aspectValue = (AspectValue) depAspects.get(aspectKey).get();
            } catch (NoSuchThingException e) {
                throw new AspectCreationException(String.format("Evaluation of aspect %s on %s failed: %s", depAspect.getAspect().getAspectClass().getName(), dep.getLabel(), e.toString()));
            }
            if (aspectValue == null) {
                // Dependent aspect has either not been computed yet or is in error.
                return null;
            }
            if (!aspectMatchesConfiguredTarget(depConfiguredTarget, aspectValue.getAspect())) {
                continue;
            }
            result.put(depKey, aspectValue.getConfiguredAspect());
            transitivePackages.addTransitive(aspectValue.getTransitivePackages());
        }
    }
    return result;
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) ConfiguredAspect(com.google.devtools.build.lib.analysis.ConfiguredAspect) ConfiguredTarget(com.google.devtools.build.lib.analysis.ConfiguredTarget) MergedConfiguredTarget(com.google.devtools.build.lib.analysis.MergedConfiguredTarget) Dependency(com.google.devtools.build.lib.analysis.Dependency) ValueOrException2(com.google.devtools.build.skyframe.ValueOrException2) AspectCreationException(com.google.devtools.build.lib.skyframe.AspectFunction.AspectCreationException) NoSuchThingException(com.google.devtools.build.lib.packages.NoSuchThingException) AspectDeps(com.google.devtools.build.lib.analysis.AspectCollection.AspectDeps) AspectDescriptor(com.google.devtools.build.lib.packages.AspectDescriptor) HashSet(java.util.HashSet) Nullable(javax.annotation.Nullable)

Example 7 with ValueOrException2

use of com.google.devtools.build.skyframe.ValueOrException2 in project bazel by bazelbuild.

the class CompletionFunction method compute.

@Nullable
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws CompletionFunctionException, InterruptedException {
    TValue value = completor.getValueFromSkyKey(skyKey, env);
    TopLevelArtifactContext topLevelContext = completor.getTopLevelArtifactContext(skyKey);
    if (env.valuesMissing()) {
        return null;
    }
    Map<SkyKey, ValueOrException2<MissingInputFileException, ActionExecutionException>> inputDeps = env.getValuesOrThrow(ArtifactSkyKey.mandatoryKeys(completor.getAllArtifactsToBuild(value, topLevelContext).getAllArtifacts()), MissingInputFileException.class, ActionExecutionException.class);
    int missingCount = 0;
    ActionExecutionException firstActionExecutionException = null;
    MissingInputFileException missingInputException = null;
    NestedSetBuilder<Cause> rootCausesBuilder = NestedSetBuilder.stableOrder();
    for (Map.Entry<SkyKey, ValueOrException2<MissingInputFileException, ActionExecutionException>> depsEntry : inputDeps.entrySet()) {
        Artifact input = ArtifactSkyKey.artifact(depsEntry.getKey());
        try {
            depsEntry.getValue().get();
        } catch (MissingInputFileException e) {
            missingCount++;
            final Label inputOwner = input.getOwner();
            if (inputOwner != null) {
                Cause cause = new LabelCause(inputOwner);
                rootCausesBuilder.add(cause);
                env.getListener().handle(completor.getRootCauseError(value, cause));
            }
        } catch (ActionExecutionException e) {
            rootCausesBuilder.addTransitive(e.getRootCauses());
            if (firstActionExecutionException == null) {
                firstActionExecutionException = e;
            }
        }
    }
    if (missingCount > 0) {
        missingInputException = completor.getMissingFilesException(value, missingCount);
    }
    NestedSet<Cause> rootCauses = rootCausesBuilder.build();
    if (!rootCauses.isEmpty()) {
        eventBusRef.get().post(completor.createFailed(value, rootCauses));
        if (firstActionExecutionException != null) {
            throw new CompletionFunctionException(firstActionExecutionException);
        } else {
            throw new CompletionFunctionException(missingInputException);
        }
    }
    return env.valuesMissing() ? null : completor.createResult(value);
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) Label(com.google.devtools.build.lib.cmdline.Label) ValueOrException2(com.google.devtools.build.skyframe.ValueOrException2) Artifact(com.google.devtools.build.lib.actions.Artifact) Cause(com.google.devtools.build.lib.causes.Cause) LabelCause(com.google.devtools.build.lib.causes.LabelCause) LabelCause(com.google.devtools.build.lib.causes.LabelCause) TopLevelArtifactContext(com.google.devtools.build.lib.analysis.TopLevelArtifactContext) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException) Map(java.util.Map) MissingInputFileException(com.google.devtools.build.lib.actions.MissingInputFileException) Nullable(javax.annotation.Nullable)

Example 8 with ValueOrException2

use of com.google.devtools.build.skyframe.ValueOrException2 in project bazel by bazelbuild.

the class PackageFunction method fetchImportsFromBuildFile.

/**
   * Fetch the skylark loads for this BUILD file. If any of them haven't been computed yet,
   * returns null.
   */
@Nullable
static SkylarkImportResult fetchImportsFromBuildFile(Path buildFilePath, PackageIdentifier packageId, BuildFileAST buildFileAST, Environment env, SkylarkImportLookupFunction skylarkImportLookupFunctionForInlining) throws NoSuchPackageException, InterruptedException {
    Preconditions.checkArgument(!packageId.getRepository().isDefault());
    ImmutableList<SkylarkImport> imports = buildFileAST.getImports();
    Map<String, Extension> importMap = Maps.newHashMapWithExpectedSize(imports.size());
    ImmutableList.Builder<SkylarkFileDependency> fileDependencies = ImmutableList.builder();
    ImmutableMap<String, Label> importPathMap;
    // Find the labels corresponding to the load statements.
    Label labelForCurrBuildFile;
    try {
        labelForCurrBuildFile = Label.create(packageId, "BUILD");
    } catch (LabelSyntaxException e) {
        // Shouldn't happen; the Label is well-formed by construction.
        throw new IllegalStateException(e);
    }
    try {
        importPathMap = SkylarkImportLookupFunction.findLabelsForLoadStatements(imports, labelForCurrBuildFile, env);
        if (importPathMap == null) {
            return null;
        }
    } catch (SkylarkImportFailedException e) {
        throw new BuildFileContainsErrorsException(packageId, e.getMessage());
    }
    // Look up and load the imports.
    ImmutableCollection<Label> importLabels = importPathMap.values();
    List<SkyKey> importLookupKeys = Lists.newArrayListWithExpectedSize(importLabels.size());
    boolean inWorkspace = buildFilePath.getBaseName().endsWith("WORKSPACE");
    for (Label importLabel : importLabels) {
        importLookupKeys.add(SkylarkImportLookupValue.key(importLabel, inWorkspace));
    }
    Map<SkyKey, SkyValue> skylarkImportMap = Maps.newHashMapWithExpectedSize(importPathMap.size());
    boolean valuesMissing = false;
    try {
        if (skylarkImportLookupFunctionForInlining == null) {
            // Not inlining
            Map<SkyKey, ValueOrException2<SkylarkImportFailedException, InconsistentFilesystemException>> skylarkLookupResults = env.getValuesOrThrow(importLookupKeys, SkylarkImportFailedException.class, InconsistentFilesystemException.class);
            valuesMissing = env.valuesMissing();
            for (Map.Entry<SkyKey, ValueOrException2<SkylarkImportFailedException, InconsistentFilesystemException>> entry : skylarkLookupResults.entrySet()) {
                // Fetching the value will raise any deferred exceptions
                skylarkImportMap.put(entry.getKey(), entry.getValue().get());
            }
        } else {
            // Inlining calls to SkylarkImportLookupFunction
            LinkedHashMap<Label, SkylarkImportLookupValue> alreadyVisitedImports = Maps.newLinkedHashMapWithExpectedSize(importLookupKeys.size());
            for (SkyKey importLookupKey : importLookupKeys) {
                SkyValue skyValue = skylarkImportLookupFunctionForInlining.computeWithInlineCalls(importLookupKey, env, alreadyVisitedImports);
                if (skyValue == null) {
                    Preconditions.checkState(env.valuesMissing(), "no skylark import value for %s", importLookupKey);
                    // We continue making inline calls even if some requested values are missing, to
                    // maximize the number of dependent (non-inlined) SkyFunctions that are requested, thus
                    // avoiding a quadratic number of restarts.
                    valuesMissing = true;
                } else {
                    skylarkImportMap.put(importLookupKey, skyValue);
                }
            }
        }
    } catch (SkylarkImportFailedException e) {
        throw new BuildFileContainsErrorsException(packageId, e.getMessage());
    } catch (InconsistentFilesystemException e) {
        throw new NoSuchPackageException(packageId, e.getMessage(), e);
    }
    if (valuesMissing) {
        // Some imports are unavailable.
        return null;
    }
    // Process the loaded imports.
    for (Entry<String, Label> importEntry : importPathMap.entrySet()) {
        String importString = importEntry.getKey();
        Label importLabel = importEntry.getValue();
        SkyKey keyForLabel = SkylarkImportLookupValue.key(importLabel, inWorkspace);
        SkylarkImportLookupValue importLookupValue = (SkylarkImportLookupValue) skylarkImportMap.get(keyForLabel);
        importMap.put(importString, importLookupValue.getEnvironmentExtension());
        fileDependencies.add(importLookupValue.getDependency());
    }
    return new SkylarkImportResult(importMap, transitiveClosureOfLabels(fileDependencies.build()));
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) Label(com.google.devtools.build.lib.cmdline.Label) SkyValue(com.google.devtools.build.skyframe.SkyValue) SkyKey(com.google.devtools.build.skyframe.SkyKey) BuildFileContainsErrorsException(com.google.devtools.build.lib.packages.BuildFileContainsErrorsException) LabelSyntaxException(com.google.devtools.build.lib.cmdline.LabelSyntaxException) ValueOrException2(com.google.devtools.build.skyframe.ValueOrException2) SkylarkImport(com.google.devtools.build.lib.syntax.SkylarkImport) Extension(com.google.devtools.build.lib.syntax.Environment.Extension) NoSuchPackageException(com.google.devtools.build.lib.packages.NoSuchPackageException) SkylarkImportFailedException(com.google.devtools.build.lib.skyframe.SkylarkImportLookupFunction.SkylarkImportFailedException) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Nullable(javax.annotation.Nullable)

Example 9 with ValueOrException2

use of com.google.devtools.build.skyframe.ValueOrException2 in project bazel by bazelbuild.

the class ActionExecutionFunction method compute.

@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws ActionExecutionFunctionException, InterruptedException {
    Preconditions.checkArgument(skyKey.argument() instanceof Action);
    Action action = (Action) skyKey.argument();
    // BUILD_ID, forcing invalidation of upward transitive closure on each build.
    if ((action.isVolatile() && !(action instanceof SkyframeAwareAction)) || action instanceof NotifyOnActionCacheHit) {
        // Volatile build actions may need to execute even if none of their known inputs have changed.
        // Depending on the buildID ensure that these actions have a chance to execute.
        PrecomputedValue.BUILD_ID.get(env);
    }
    // Look up the parts of the environment that influence the action.
    Map<SkyKey, SkyValue> clientEnvLookup = env.getValues(Iterables.transform(action.getClientEnvironmentVariables(), VAR_TO_SKYKEY));
    if (env.valuesMissing()) {
        return null;
    }
    Map<String, String> clientEnv = new HashMap<>();
    for (Entry<SkyKey, SkyValue> entry : clientEnvLookup.entrySet()) {
        ClientEnvironmentValue envValue = (ClientEnvironmentValue) entry.getValue();
        if (envValue.getValue() != null) {
            clientEnv.put((String) entry.getKey().argument(), envValue.getValue());
        }
    }
    // For restarts of this ActionExecutionFunction we use a ContinuationState variable, below, to
    // avoid redoing work. However, if two actions are shared and the first one executes, when the
    // second one goes to execute, we should detect that and short-circuit, even without taking
    // ContinuationState into account.
    boolean sharedActionAlreadyRan = skyframeActionExecutor.probeActionExecution(action);
    ContinuationState state;
    if (action.discoversInputs()) {
        state = getState(action);
    } else {
        // Because this is a new state, all conditionals below about whether state has already done
        // something will return false, and so we will execute all necessary steps.
        state = new ContinuationState();
    }
    if (!state.hasCollectedInputs()) {
        state.allInputs = collectInputs(action, env);
        if (state.allInputs == null) {
            // Missing deps.
            return null;
        }
    } else if (state.allInputs.keysRequested != null) {
        // Preserve the invariant that we ask for the same deps each build.
        env.getValues(state.allInputs.keysRequested);
        Preconditions.checkState(!env.valuesMissing(), "%s %s", action, state);
    }
    Pair<Map<Artifact, FileArtifactValue>, Map<Artifact, Collection<Artifact>>> checkedInputs = null;
    try {
        // Declare deps on known inputs to action. We do this unconditionally to maintain our
        // invariant of asking for the same deps each build.
        Map<SkyKey, ValueOrException2<MissingInputFileException, ActionExecutionException>> inputDeps = env.getValuesOrThrow(toKeys(state.allInputs.getAllInputs(), action.discoversInputs() ? action.getMandatoryInputs() : null), MissingInputFileException.class, ActionExecutionException.class);
        if (!sharedActionAlreadyRan && !state.hasArtifactData()) {
            // Do we actually need to find our metadata?
            checkedInputs = checkInputs(env, action, inputDeps);
        }
    } catch (ActionExecutionException e) {
        // Remove action from state map in case it's there (won't be unless it discovers inputs).
        stateMap.remove(action);
        throw new ActionExecutionFunctionException(e);
    }
    if (env.valuesMissing()) {
        // of the action; see establishSkyframeDependencies why.
        return null;
    }
    try {
        establishSkyframeDependencies(env, action);
    } catch (ActionExecutionException e) {
        throw new ActionExecutionFunctionException(e);
    }
    if (env.valuesMissing()) {
        return null;
    }
    if (checkedInputs != null) {
        Preconditions.checkState(!state.hasArtifactData(), "%s %s", state, action);
        state.inputArtifactData = checkedInputs.first;
        state.expandedArtifacts = checkedInputs.second;
    }
    ActionExecutionValue result;
    try {
        result = checkCacheAndExecuteIfNeeded(action, state, env, clientEnv);
    } catch (ActionExecutionException e) {
        // Remove action from state map in case it's there (won't be unless it discovers inputs).
        stateMap.remove(action);
        // action. Label can be null in the case of, e.g., the SystemActionOwner (for build-info.txt).
        throw new ActionExecutionFunctionException(new AlreadyReportedActionExecutionException(e));
    }
    if (env.valuesMissing()) {
        Preconditions.checkState(stateMap.containsKey(action), action);
        return null;
    }
    // Remove action from state map in case it's there (won't be unless it discovers inputs).
    stateMap.remove(action);
    return result;
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) Action(com.google.devtools.build.lib.actions.Action) HashMap(java.util.HashMap) NotifyOnActionCacheHit(com.google.devtools.build.lib.actions.NotifyOnActionCacheHit) ValueOrException2(com.google.devtools.build.skyframe.ValueOrException2) Artifact(com.google.devtools.build.lib.actions.Artifact) SkyValue(com.google.devtools.build.skyframe.SkyValue) AlreadyReportedActionExecutionException(com.google.devtools.build.lib.actions.AlreadyReportedActionExecutionException) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) Map(java.util.Map) AlreadyReportedActionExecutionException(com.google.devtools.build.lib.actions.AlreadyReportedActionExecutionException)

Aggregations

SkyKey (com.google.devtools.build.skyframe.SkyKey)9 ValueOrException2 (com.google.devtools.build.skyframe.ValueOrException2)9 Label (com.google.devtools.build.lib.cmdline.Label)6 NoSuchPackageException (com.google.devtools.build.lib.packages.NoSuchPackageException)4 HashMap (java.util.HashMap)4 Map (java.util.Map)4 Nullable (javax.annotation.Nullable)4 ActionExecutionException (com.google.devtools.build.lib.actions.ActionExecutionException)3 Artifact (com.google.devtools.build.lib.actions.Artifact)3 NoSuchTargetException (com.google.devtools.build.lib.packages.NoSuchTargetException)3 SkyValue (com.google.devtools.build.skyframe.SkyValue)3 ImmutableList (com.google.common.collect.ImmutableList)2 ImmutableMap (com.google.common.collect.ImmutableMap)2 AlreadyReportedActionExecutionException (com.google.devtools.build.lib.actions.AlreadyReportedActionExecutionException)2 MissingInputFileException (com.google.devtools.build.lib.actions.MissingInputFileException)2 Cause (com.google.devtools.build.lib.causes.Cause)2 LabelCause (com.google.devtools.build.lib.causes.LabelCause)2 LabelSyntaxException (com.google.devtools.build.lib.cmdline.LabelSyntaxException)2 ConcurrentMap (java.util.concurrent.ConcurrentMap)2 Action (com.google.devtools.build.lib.actions.Action)1