Skip to content

Commit 05b9739

Browse files
coeuvrecopybara-github
authored andcommitted
Assign priority to input prefech tasks.
High priority tasks are tasks that are critical to the build wall time e.g. staging inputs to local actions. Low priority tasks are tasks that don't have impact on wall time e.g. staging outputs of toplevel targets/aspects. By assiging priority to these tasks, we can reduce the wall time when the network traffic is high by prioritizing high priority tasks. PiperOrigin-RevId: 475296193 Change-Id: I961a9e55fb7b563a6813ceef7e58f0cb275a687b
1 parent b52c09b commit 05b9739

File tree

5 files changed

+48
-24
lines changed

5 files changed

+48
-24
lines changed

src/main/java/com/google/devtools/build/lib/exec/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ java_library(
282282
"//src/main/java/com/google/devtools/build/lib/actions",
283283
"//src/main/java/com/google/devtools/build/lib/actions:artifacts",
284284
"//src/main/java/com/google/devtools/build/lib/events",
285+
"//src/main/java/com/google/devtools/build/lib/profiler",
285286
"//src/main/java/com/google/devtools/build/lib/util/io",
286287
"//src/main/java/com/google/devtools/build/lib/vfs",
287288
"//src/main/java/com/google/devtools/build/lib/vfs:pathfragment",

src/main/java/com/google/devtools/build/lib/exec/SpawnRunner.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
import com.google.devtools.build.lib.actions.SpawnResult;
3131
import com.google.devtools.build.lib.actions.cache.MetadataInjector;
3232
import com.google.devtools.build.lib.events.ExtendedEventHandler;
33+
import com.google.devtools.build.lib.profiler.Profiler;
34+
import com.google.devtools.build.lib.profiler.ProfilerTask;
35+
import com.google.devtools.build.lib.profiler.SilentCloseable;
3336
import com.google.devtools.build.lib.util.io.FileOutErr;
3437
import com.google.devtools.build.lib.vfs.FileSystem;
3538
import com.google.devtools.build.lib.vfs.Path;
@@ -161,7 +164,8 @@ interface SpawnExecutionContext {
161164
default void prefetchInputsAndWait()
162165
throws IOException, InterruptedException, ForbiddenActionInputException {
163166
ListenableFuture<Void> future = prefetchInputs();
164-
try {
167+
try (SilentCloseable s =
168+
Profiler.instance().profile(ProfilerTask.REMOTE_DOWNLOAD, "stage remote inputs")) {
165169
future.get();
166170
} catch (ExecutionException e) {
167171
Throwable cause = e.getCause();

src/main/java/com/google/devtools/build/lib/remote/AbstractActionInputPrefetcher.java

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@
3333
import com.google.devtools.build.lib.actions.FileArtifactValue;
3434
import com.google.devtools.build.lib.actions.MetadataProvider;
3535
import com.google.devtools.build.lib.actions.cache.VirtualActionInput;
36-
import com.google.devtools.build.lib.profiler.Profiler;
37-
import com.google.devtools.build.lib.profiler.ProfilerTask;
38-
import com.google.devtools.build.lib.profiler.SilentCloseable;
3936
import com.google.devtools.build.lib.remote.util.AsyncTaskCache;
4037
import com.google.devtools.build.lib.remote.util.RxUtils.TransferResult;
4138
import com.google.devtools.build.lib.remote.util.TempPathGenerator;
@@ -64,6 +61,20 @@ public abstract class AbstractActionInputPrefetcher implements ActionInputPrefet
6461

6562
protected final Path execRoot;
6663

64+
/** Priority for the staging task. */
65+
protected enum Priority {
66+
/**
67+
* High priority tasks are tasks that are critical to the wall time e.g. staging inputs to local
68+
* actions.
69+
*/
70+
HIGH,
71+
/**
72+
* Low priority tasks are tasks that don't have impact on the wall time e.g. staging outputs of
73+
* toplevel targets/aspects.
74+
*/
75+
LOW,
76+
}
77+
6778
protected AbstractActionInputPrefetcher(Path execRoot, TempPathGenerator tempPathGenerator) {
6879
this.execRoot = execRoot;
6980
this.tempPathGenerator = tempPathGenerator;
@@ -77,7 +88,7 @@ protected AbstractActionInputPrefetcher(Path execRoot, TempPathGenerator tempPat
7788
* @param tempPath the temporary path which the input should be written to.
7889
*/
7990
protected abstract ListenableFuture<Void> doDownloadFile(
80-
Path tempPath, FileArtifactValue metadata) throws IOException;
91+
Path tempPath, FileArtifactValue metadata, Priority priority) throws IOException;
8192

8293
protected void prefetchVirtualActionInput(VirtualActionInput input) throws IOException {}
8394

@@ -98,6 +109,13 @@ protected Completable onErrorResumeNext(Throwable error) {
98109
@Override
99110
public ListenableFuture<Void> prefetchFiles(
100111
Iterable<? extends ActionInput> inputs, MetadataProvider metadataProvider) {
112+
return prefetchFiles(inputs, metadataProvider, Priority.HIGH);
113+
}
114+
115+
protected ListenableFuture<Void> prefetchFiles(
116+
Iterable<? extends ActionInput> inputs,
117+
MetadataProvider metadataProvider,
118+
Priority priority) {
101119
Map<SpecialArtifact, List<TreeFileArtifact>> trees = new HashMap<>();
102120
List<ActionInput> files = new ArrayList<>();
103121
for (ActionInput input : inputs) {
@@ -120,22 +138,22 @@ public ListenableFuture<Void> prefetchFiles(
120138
.flatMapSingle(
121139
entry ->
122140
toTransferResult(
123-
prefetchInputTree(metadataProvider, entry.getKey(), entry.getValue())));
141+
prefetchInputTree(
142+
metadataProvider, entry.getKey(), entry.getValue(), priority)));
124143
Flowable<TransferResult> fileDownloads =
125144
Flowable.fromIterable(files)
126-
.flatMapSingle(input -> toTransferResult(prefetchInputFile(metadataProvider, input)));
145+
.flatMapSingle(
146+
input -> toTransferResult(prefetchInputFile(metadataProvider, input, priority)));
127147
Flowable<TransferResult> transfers = Flowable.merge(treeDownloads, fileDownloads);
128148
Completable prefetch = mergeBulkTransfer(transfers).onErrorResumeNext(this::onErrorResumeNext);
129-
Completable prefetchWithProfiler =
130-
Completable.using(
131-
() -> Profiler.instance().profile(ProfilerTask.REMOTE_DOWNLOAD, "stage remote inputs"),
132-
profiler -> prefetch,
133-
SilentCloseable::close);
134-
return toListenableFuture(prefetchWithProfiler);
149+
return toListenableFuture(prefetch);
135150
}
136151

137152
private Completable prefetchInputTree(
138-
MetadataProvider provider, SpecialArtifact tree, List<TreeFileArtifact> treeFiles) {
153+
MetadataProvider provider,
154+
SpecialArtifact tree,
155+
List<TreeFileArtifact> treeFiles,
156+
Priority priority) {
139157
Path treeRoot = execRoot.getRelative(tree.getExecPath());
140158
HashMap<TreeFileArtifact, Path> treeFileTmpPathMap = new HashMap<>();
141159

@@ -153,7 +171,8 @@ private Completable prefetchInputTree(
153171
treeFileTmpPathMap.put(treeFile, tempPath);
154172

155173
return toTransferResult(
156-
toCompletable(() -> doDownloadFile(tempPath, metadata), directExecutor()));
174+
toCompletable(
175+
() -> doDownloadFile(tempPath, metadata, priority), directExecutor()));
157176
});
158177

159178
AtomicBoolean completed = new AtomicBoolean();
@@ -211,8 +230,8 @@ private Completable prefetchInputTree(
211230
return downloadCache.executeIfNot(treeRoot, download);
212231
}
213232

214-
private Completable prefetchInputFile(MetadataProvider metadataProvider, ActionInput input)
215-
throws IOException {
233+
private Completable prefetchInputFile(
234+
MetadataProvider metadataProvider, ActionInput input, Priority priority) throws IOException {
216235
if (input instanceof VirtualActionInput) {
217236
prefetchVirtualActionInput((VirtualActionInput) input);
218237
return Completable.complete();
@@ -224,7 +243,7 @@ private Completable prefetchInputFile(MetadataProvider metadataProvider, ActionI
224243
}
225244

226245
Path path = execRoot.getRelative(input.getExecPath());
227-
return downloadFileRx(path, metadata);
246+
return downloadFileRx(path, metadata, priority);
228247
}
229248

230249
/**
@@ -233,7 +252,7 @@ private Completable prefetchInputFile(MetadataProvider metadataProvider, ActionI
233252
* <p>The file will be written into a temporary file and moved to the final destination after the
234253
* download finished.
235254
*/
236-
public Completable downloadFileRx(Path path, FileArtifactValue metadata) {
255+
public Completable downloadFileRx(Path path, FileArtifactValue metadata, Priority priority) {
237256
if (!shouldDownloadFile(path, metadata)) {
238257
return Completable.complete();
239258
}
@@ -253,7 +272,7 @@ public Completable downloadFileRx(Path path, FileArtifactValue metadata) {
253272
Completable.using(
254273
tempPathGenerator::generateTempPath,
255274
tempPath ->
256-
toCompletable(() -> doDownloadFile(tempPath, metadata), directExecutor())
275+
toCompletable(() -> doDownloadFile(tempPath, metadata, priority), directExecutor())
257276
.doOnComplete(
258277
() -> {
259278
finalizeDownload(tempPath, finalPath);
@@ -277,7 +296,7 @@ public Completable downloadFileRx(Path path, FileArtifactValue metadata) {
277296
* download finished.
278297
*/
279298
public ListenableFuture<Void> downloadFileAsync(Path path, FileArtifactValue metadata) {
280-
return toListenableFuture(downloadFileRx(path, metadata));
299+
return toListenableFuture(downloadFileRx(path, metadata, Priority.LOW));
281300
}
282301

283302
/**

src/main/java/com/google/devtools/build/lib/remote/RemoteActionInputFetcher.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ protected boolean shouldDownloadFile(Path path, FileArtifactValue metadata) {
7171
}
7272

7373
@Override
74-
protected ListenableFuture<Void> doDownloadFile(Path tempPath, FileArtifactValue metadata)
75-
throws IOException {
74+
protected ListenableFuture<Void> doDownloadFile(
75+
Path tempPath, FileArtifactValue metadata, Priority priority) throws IOException {
7676
checkArgument(metadata.isRemote(), "Cannot download file that is not a remote file.");
7777
RequestMetadata requestMetadata =
7878
TracingMetadataUtils.buildMetadata(buildRequestId, commandId, metadata.getActionId(), null);

src/test/java/com/google/devtools/build/lib/remote/ActionInputPrefetcherTestBase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ protected static void mockDownload(
386386
return resultSupplier.get();
387387
})
388388
.when(prefetcher)
389-
.doDownloadFile(any(), any());
389+
.doDownloadFile(any(), any(), any());
390390
}
391391

392392
private void assertReadableNonWritableAndExecutable(Path path) throws IOException {

0 commit comments

Comments
 (0)