Search in sources :

Example 1 with NotifyOnActionCacheHit

use of com.google.devtools.build.lib.actions.NotifyOnActionCacheHit in project bazel by bazelbuild.

the class SkyframeActionExecutor method checkActionCache.

/**
   * Checks the action cache to see if {@code action} needs to be executed, or is up to date.
   * Returns a token with the semantics of {@link ActionCacheChecker#getTokenIfNeedToExecute}: null
   * if the action is up to date, and non-null if it needs to be executed, in which case that token
   * should be provided to the ActionCacheChecker after execution.
   */
Token checkActionCache(Action action, MetadataHandler metadataHandler, long actionStartTime, Iterable<Artifact> resolvedCacheArtifacts, Map<String, String> clientEnv) {
    profiler.startTask(ProfilerTask.ACTION_CHECK, action);
    Token token = actionCacheChecker.getTokenIfNeedToExecute(action, resolvedCacheArtifacts, clientEnv, explain ? reporter : null, metadataHandler);
    profiler.completeTask(ProfilerTask.ACTION_CHECK);
    if (token == null) {
        boolean eventPosted = false;
        // Notify BlazeRuntimeStatistics about the action middleman 'execution'.
        if (action.getActionType().isMiddleman()) {
            postEvent(new ActionMiddlemanEvent(action, actionStartTime));
            eventPosted = true;
        }
        if (action instanceof NotifyOnActionCacheHit) {
            NotifyOnActionCacheHit notify = (NotifyOnActionCacheHit) action;
            notify.actionCacheHit(executorEngine);
        }
        // We still need to check the outputs so that output file data is available to the value.
        checkOutputs(action, metadataHandler);
        if (!eventPosted) {
            postEvent(new CachedActionEvent(action, actionStartTime));
        }
    }
    return token;
}
Also used : CachedActionEvent(com.google.devtools.build.lib.actions.CachedActionEvent) NotifyOnActionCacheHit(com.google.devtools.build.lib.actions.NotifyOnActionCacheHit) Token(com.google.devtools.build.lib.actions.ActionCacheChecker.Token) ActionMiddlemanEvent(com.google.devtools.build.lib.actions.ActionMiddlemanEvent)

Example 2 with NotifyOnActionCacheHit

use of com.google.devtools.build.lib.actions.NotifyOnActionCacheHit 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

NotifyOnActionCacheHit (com.google.devtools.build.lib.actions.NotifyOnActionCacheHit)2 Action (com.google.devtools.build.lib.actions.Action)1 Token (com.google.devtools.build.lib.actions.ActionCacheChecker.Token)1 ActionExecutionException (com.google.devtools.build.lib.actions.ActionExecutionException)1 ActionMiddlemanEvent (com.google.devtools.build.lib.actions.ActionMiddlemanEvent)1 AlreadyReportedActionExecutionException (com.google.devtools.build.lib.actions.AlreadyReportedActionExecutionException)1 Artifact (com.google.devtools.build.lib.actions.Artifact)1 CachedActionEvent (com.google.devtools.build.lib.actions.CachedActionEvent)1 SkyKey (com.google.devtools.build.skyframe.SkyKey)1 SkyValue (com.google.devtools.build.skyframe.SkyValue)1 ValueOrException2 (com.google.devtools.build.skyframe.ValueOrException2)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 ConcurrentMap (java.util.concurrent.ConcurrentMap)1