Track the time spent in source and output-tree diff checking.
PiperOrigin-RevId: 233971847
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionFinishedEvent.java b/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionFinishedEvent.java
deleted file mode 100644
index 33c1baa..0000000
--- a/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionFinishedEvent.java
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2014 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-package com.google.devtools.build.lib.buildtool;
-
-import com.google.common.collect.ImmutableMap;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Event signaling the end of the execution phase. Contains statistics about the action cache,
- * the metadata cache and about last file save times.
- */
-public class ExecutionFinishedEvent {
-
- private final int outputDirtyFiles;
- private final int outputModifiedFilesDuringPreviousBuild;
- /** The mtime of the most recently saved source file when the build starts. */
- private long lastFileSaveTimeInMillis;
-
- /**
- * The (filename, mtime) pairs of all files saved between the last build's
- * start time and the current build's start time. Only applies to builds
- * running with existing Blaze servers. Currently disabled.
- */
- private Map<String, Long> changedFileSaveTimes = new HashMap<>();
-
- public ExecutionFinishedEvent(Map<String, Long> changedFileSaveTimes,
- long lastFileSaveTimeInMillis, int outputDirtyFiles,
- int outputModifiedFilesDuringPreviousBuild) {
- this.outputDirtyFiles = outputDirtyFiles;
- this.outputModifiedFilesDuringPreviousBuild = outputModifiedFilesDuringPreviousBuild;
- this.changedFileSaveTimes = ImmutableMap.copyOf(changedFileSaveTimes);
- this.lastFileSaveTimeInMillis = lastFileSaveTimeInMillis;
- }
-
- public long getLastFileSaveTimeInMillis() {
- return lastFileSaveTimeInMillis;
- }
-
- public int getOutputDirtyFiles() {
- return outputDirtyFiles;
- }
-
- public int getOutputModifiedFilesDuringPreviousBuild() {
- return outputModifiedFilesDuringPreviousBuild;
- }
-
- public Map<String, Long> getChangedFileSaveTimes() {
- return changedFileSaveTimes;
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java b/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java
index 2445087..40b8887 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/ExecutionTool.java
@@ -368,13 +368,7 @@
// Handlers process these events and others (e.g. CommandCompleteEvent), even in the event of
// a catastrophic failure. Posting these is consistent with other behavior.
- env.getEventBus()
- .post(
- new ExecutionFinishedEvent(
- ImmutableMap.of(),
- 0L,
- skyframeExecutor.getOutputDirtyFilesAndClear(),
- skyframeExecutor.getModifiedFilesDuringPreviousBuildAndClear()));
+ env.getEventBus().post(skyframeExecutor.createExecutionFinishedEvent());
env.getEventBus()
.post(new ExecutionPhaseCompleteEvent(timer.stop().elapsed(TimeUnit.MILLISECONDS)));
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/SkyframeBuilder.java b/src/main/java/com/google/devtools/build/lib/buildtool/SkyframeBuilder.java
index 7ae88b4..d77ef7f 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/SkyframeBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/SkyframeBuilder.java
@@ -107,9 +107,7 @@
@Nullable Range<Long> lastExecutionTimeRange,
TopLevelArtifactContext topLevelArtifactContext)
throws BuildFailedException, AbruptExitException, TestExecException, InterruptedException {
- try (SilentCloseable c = Profiler.instance().profile("detectModifiedOutputFiles")) {
- skyframeExecutor.detectModifiedOutputFiles(modifiedOutputFiles, lastExecutionTimeRange);
- }
+ skyframeExecutor.detectModifiedOutputFiles(modifiedOutputFiles, lastExecutionTimeRange);
try (SilentCloseable c = Profiler.instance().profile("configureActionExecutor")) {
skyframeExecutor.configureActionExecutor(fileCache, actionInputPrefetcher);
}
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BuildSummaryStatsModule.java b/src/main/java/com/google/devtools/build/lib/runtime/BuildSummaryStatsModule.java
index 6c7a4d7..f906215 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BuildSummaryStatsModule.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BuildSummaryStatsModule.java
@@ -20,7 +20,6 @@
import com.google.devtools.build.lib.actions.ActionKeyContext;
import com.google.devtools.build.lib.actions.ActionResultReceivedEvent;
import com.google.devtools.build.lib.buildtool.BuildRequest;
-import com.google.devtools.build.lib.buildtool.ExecutionFinishedEvent;
import com.google.devtools.build.lib.buildtool.buildevent.BuildCompleteEvent;
import com.google.devtools.build.lib.buildtool.buildevent.ExecutionStartingEvent;
import com.google.devtools.build.lib.clock.BlazeClock;
@@ -31,6 +30,7 @@
import com.google.devtools.build.lib.profiler.Profiler;
import com.google.devtools.build.lib.profiler.ProfilerTask;
import com.google.devtools.build.lib.profiler.SilentCloseable;
+import com.google.devtools.build.lib.skyframe.ExecutionFinishedEvent;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ExecutionFinishedEvent.java b/src/main/java/com/google/devtools/build/lib/skyframe/ExecutionFinishedEvent.java
new file mode 100644
index 0000000..8db7f9e
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ExecutionFinishedEvent.java
@@ -0,0 +1,57 @@
+// Copyright 2014 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.skyframe;
+
+import java.time.Duration;
+
+/**
+ * Event signaling the end of the execution phase. Contains statistics about the action cache,
+ * the metadata cache and about last file save times.
+ */
+public class ExecutionFinishedEvent {
+ public static final ExecutionFinishedEvent EMPTY =
+ new ExecutionFinishedEvent(0, 0, Duration.ZERO, Duration.ZERO);
+
+ private final int outputDirtyFiles;
+ private final int outputModifiedFilesDuringPreviousBuild;
+ private final Duration sourceDiffCheckingDuration;
+ private final Duration outputTreeDiffCheckingDuration;
+
+ ExecutionFinishedEvent(
+ int outputDirtyFiles,
+ int outputModifiedFilesDuringPreviousBuild,
+ Duration sourceDiffCheckingDuration,
+ Duration outputTreeDiffCheckingDuration) {
+ this.outputDirtyFiles = outputDirtyFiles;
+ this.outputModifiedFilesDuringPreviousBuild = outputModifiedFilesDuringPreviousBuild;
+ this.sourceDiffCheckingDuration = sourceDiffCheckingDuration;
+ this.outputTreeDiffCheckingDuration = outputTreeDiffCheckingDuration;
+ }
+
+ public int getOutputDirtyFiles() {
+ return outputDirtyFiles;
+ }
+
+ public int getOutputModifiedFilesDuringPreviousBuild() {
+ return outputModifiedFilesDuringPreviousBuild;
+ }
+
+ public Duration getSourceDiffCheckingDuration() {
+ return sourceDiffCheckingDuration;
+ }
+
+ public Duration getOutputTreeDiffCheckingDuration() {
+ return outputTreeDiffCheckingDuration;
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java
index 2c97847..1c051f3 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java
@@ -55,6 +55,7 @@
import com.google.devtools.build.lib.pkgcache.PackageCacheOptions;
import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
import com.google.devtools.build.lib.profiler.Profiler;
+import com.google.devtools.build.lib.profiler.ProfilerTask;
import com.google.devtools.build.lib.profiler.SilentCloseable;
import com.google.devtools.build.lib.query2.AqueryActionFilter;
import com.google.devtools.build.lib.skyframe.AspectValue.AspectKey;
@@ -93,6 +94,7 @@
import com.google.devtools.build.skyframe.SkyValue;
import com.google.devtools.common.options.OptionsProvider;
import java.io.PrintStream;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
@@ -133,6 +135,12 @@
private final Iterable<SkyValueDirtinessChecker> customDirtinessCheckers;
private Set<String> previousClientEnvironment = ImmutableSet.of();
+ private int modifiedFiles;
+ private int outputDirtyFiles;
+ private int modifiedFilesDuringPreviousBuild;
+ private Duration sourceDiffCheckingDuration;
+ private Duration outputTreeDiffCheckingDuration;
+
private SequencedSkyframeExecutor(
Consumer<SkyframeExecutor> skyframeExecutorConsumerOnInit,
EvaluatorSupplier evaluatorSupplier,
@@ -309,9 +317,12 @@
clientEnv,
tsgm,
options);
- try (SilentCloseable c = Profiler.instance().profile("handleDiffs")) {
- handleDiffs(eventHandler, packageCacheOptions.checkOutputFiles, options);
- }
+ long startTime = System.nanoTime();
+ handleDiffs(eventHandler, packageCacheOptions.checkOutputFiles, options);
+ long stopTime = System.nanoTime();
+ Profiler.instance().logSimpleTask(startTime, stopTime, ProfilerTask.INFO, "handleDiffs");
+ long duration = stopTime - startTime;
+ sourceDiffCheckingDuration = duration > 0 ? Duration.ofNanos(duration) : Duration.ZERO;
}
/**
@@ -674,9 +685,8 @@
@Override
public void detectModifiedOutputFiles(
ModifiedFileSet modifiedOutputFiles, @Nullable Range<Long> lastExecutionTimeRange)
- throws AbruptExitException, InterruptedException {
-
- // Detect external modifications in the output tree.
+ throws InterruptedException {
+ long startTime = System.nanoTime();
FilesystemValueChecker fsvc =
new FilesystemValueChecker(Preconditions.checkNotNull(tsgm.get()), lastExecutionTimeRange);
BatchStat batchStatter = outputService == null ? null : outputService.getBatchStatter();
@@ -686,7 +696,12 @@
modifiedFiles += fsvc.getNumberOfModifiedOutputFiles();
outputDirtyFiles += fsvc.getNumberOfModifiedOutputFiles();
modifiedFilesDuringPreviousBuild += fsvc.getNumberOfModifiedOutputFilesDuringPreviousBuild();
- informAboutNumberOfModifiedFiles();
+ logger.info(String.format("Found %d modified files from last build", modifiedFiles));
+ long stopTime = System.nanoTime();
+ Profiler.instance()
+ .logSimpleTask(startTime, stopTime, ProfilerTask.INFO, "detectModifiedOutputFiles");
+ long duration = stopTime - startTime;
+ outputTreeDiffCheckingDuration = duration > 0 ? Duration.ofNanos(duration) : Duration.ZERO;
}
@Override
@@ -830,6 +845,21 @@
}
@Override
+ public ExecutionFinishedEvent createExecutionFinishedEvent() {
+ ExecutionFinishedEvent result =
+ new ExecutionFinishedEvent(
+ outputDirtyFiles,
+ modifiedFilesDuringPreviousBuild,
+ sourceDiffCheckingDuration,
+ outputTreeDiffCheckingDuration);
+ outputDirtyFiles = 0;
+ modifiedFilesDuringPreviousBuild = 0;
+ sourceDiffCheckingDuration = Duration.ZERO;
+ outputTreeDiffCheckingDuration = Duration.ZERO;
+ return result;
+ }
+
+ @Override
public void deleteOldNodes(long versionWindowForDirtyGc) {
// TODO(bazel-team): perhaps we should come up with a separate GC class dedicated to maintaining
// value garbage. If we ever do so, this logic should be moved there.
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
index 5593383..a94ea91 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
@@ -293,10 +293,6 @@
protected SkyframeProgressReceiver progressReceiver;
private final AtomicReference<CyclesReporter> cyclesReporter = new AtomicReference<>();
- protected int modifiedFiles;
- protected int outputDirtyFiles;
- protected int modifiedFilesDuringPreviousBuild;
-
@VisibleForTesting boolean lastAnalysisDiscarded = false;
private boolean analysisCacheDiscarded = false;
@@ -1171,16 +1167,6 @@
return new SkyFunctionEnvironmentForTesting(eventHandler, this);
}
- /**
- * Informs user about number of modified files (source and output files).
- */
- // Note, that number of modified files in some cases can be bigger than actual number of
- // modified files for targets in current request. Skyframe may check for modification all files
- // from previous requests.
- protected void informAboutNumberOfModifiedFiles() {
- logger.info(String.format("Found %d modified files from last build", modifiedFiles));
- }
-
public EventBus getEventBus() {
return eventBus.get();
}
@@ -2696,17 +2682,7 @@
}
}
- public int getOutputDirtyFilesAndClear() {
- int result = outputDirtyFiles;
- outputDirtyFiles = 0;
- return result;
- }
-
- public int getModifiedFilesDuringPreviousBuildAndClear() {
- int result = modifiedFilesDuringPreviousBuild;
- modifiedFilesDuringPreviousBuild = 0;
- return result;
- }
+ public abstract ExecutionFinishedEvent createExecutionFinishedEvent();
private <T extends SkyValue> EvaluationResult<T> evaluate(
Iterable<? extends SkyKey> roots,