Resolve inputs that were stored in action cache ahead of time so metadata for them can be retrieved with other inputs, avoiding a restart.
This also allows us to delete the UndeclaredInputsHandler, since we eagerly cache metadata before entering any ActionCacheChecker methods.
This should also allow us to split FileAndMetadataCache into two separate classes, as well as asserting that SingleBuildFileCache only sees non-artifact ActionInputs. To be done in follow-ups.
--
MOS_MIGRATED_REVID=89718712
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java b/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java
index e3a8ff8..004f2c3 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java
@@ -15,6 +15,7 @@
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Action.MiddlemanType;
import com.google.devtools.build.lib.actions.cache.ActionCache;
@@ -142,8 +143,8 @@
*/
// Note: the handler should only be used for DEPCHECKER events; there's no
// guarantee it will be available for other events.
- public Token getTokenIfNeedToExecute(Action action, EventHandler handler,
- MetadataHandler metadataHandler, PackageRootResolver resolver) {
+ public Token getTokenIfNeedToExecute(Action action, Iterable<Artifact> resolvedCacheArtifacts,
+ EventHandler handler, MetadataHandler metadataHandler) {
// TODO(bazel-team): (2010) For RunfilesAction/SymlinkAction and similar actions that
// produce only symlinks we should not check whether inputs are valid at all - all that matters
// that inputs and outputs are still exist (and new inputs have not appeared). All other checks
@@ -160,17 +161,15 @@
return null;
}
Iterable<Artifact> actionInputs = action.getInputs();
- ActionCache.Entry entry = getCacheEntry(action);
// Resolve action inputs from cache, if necessary.
boolean inputsKnown = action.inputsKnown();
- if (entry != null && !entry.isCorrupted() && !inputsKnown) {
- Preconditions.checkState(action.discoversInputs(), action);
- actionInputs = resolveCachedActionInputs(action, entry, resolver);
- if (actionInputs == null) {
- // Not all inputs could be resolved. Try again next time.
- return Token.NEED_TO_RERUN;
- }
+ if (!inputsKnown && resolvedCacheArtifacts != null) {
+ // The action doesn't know its inputs, but the caller has a good idea of what they are.
+ Preconditions.checkState(action.discoversInputs(),
+ "Actions that don't know their inputs must discover them: %s", action);
+ actionInputs = resolvedCacheArtifacts;
}
+ ActionCache.Entry entry = getCacheEntry(action);
if (mustExecute(action, entry, handler, metadataHandler, actionInputs)) {
if (entry != null) {
removeCacheEntry(action);
@@ -241,10 +240,12 @@
actionCache.put(key, entry);
}
- private Iterable<Artifact> resolveCachedActionInputs(Action action, ActionCache.Entry entry,
- PackageRootResolver resolver) {
- Preconditions.checkNotNull(entry, action);
- Preconditions.checkState(!entry.isCorrupted(), action);
+ @Nullable
+ public Iterable<Artifact> getCachedInputs(Action action, PackageRootResolver resolver) {
+ ActionCache.Entry entry = getCacheEntry(action);
+ if (entry == null || entry.isCorrupted()) {
+ return ImmutableList.of();
+ }
List<PathFragment> outputs = new ArrayList<>();
for (Artifact output : action.getOutputs()) {
@@ -353,7 +354,6 @@
/** Wrapper for all context needed by the ActionCacheChecker to handle a single action. */
public static final class Token {
- public static final Token NEED_TO_RERUN = new Token("need to rerun");
private final String cacheKey;
private Token(String cacheKey) {