Skip to content

Commit 6b52772

Browse files
coeuvrecopybara-github
authored andcommitted
Add flag --experimental_remote_build_event_upload
Add flag `--experimental_remote_build_event_upload` which controls the way Bazel uploads files referenced in BEP to remote cache. It defaults to `all` which maintains current behaviour: Bazel uploads all local files referenced by BEP to remote cache and convert their paths to `bytestream://...`. Additionally, `--incompatible_remote_build_event_upload_respect_no_cache` can be set to avoid uploading outputs that are generated by "non-remote-cachable" spawns. If set to `minimal`, local outputs are not uploaded to the remote cache, except for files that are **important** to the consumers of BES (e.g. test logs and timing profile). Paths for files that are already uploaded to the remote cache are converted. `--incompatible_remote_build_event_upload_respect_no_cache` is deprecated in favour of this new flag. Fixes #16151. Closes #16299. PiperOrigin-RevId: 476865036 Change-Id: I4c506f7447a41e8e64a4ed0785e7f20a40ea3b84
1 parent 9877fca commit 6b52772

File tree

8 files changed

+426
-22
lines changed

8 files changed

+426
-22
lines changed

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

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,17 @@
2323
import com.google.common.base.Preconditions;
2424
import com.google.common.collect.ImmutableSet;
2525
import com.google.common.collect.Sets;
26+
import com.google.common.eventbus.Subscribe;
2627
import com.google.common.util.concurrent.ListenableFuture;
2728
import com.google.devtools.build.lib.buildeventstream.BuildEvent.LocalFile;
2829
import com.google.devtools.build.lib.buildeventstream.BuildEventArtifactUploader;
2930
import com.google.devtools.build.lib.buildeventstream.PathConverter;
31+
import com.google.devtools.build.lib.buildtool.buildevent.ProfilerStartedEvent;
3032
import com.google.devtools.build.lib.events.Event;
3133
import com.google.devtools.build.lib.events.ExtendedEventHandler;
3234
import com.google.devtools.build.lib.remote.common.RemoteActionExecutionContext;
3335
import com.google.devtools.build.lib.remote.common.RemoteActionExecutionContext.CachePolicy;
36+
import com.google.devtools.build.lib.remote.options.RemoteBuildEventUploadMode;
3437
import com.google.devtools.build.lib.remote.util.DigestUtil;
3538
import com.google.devtools.build.lib.remote.util.TracingMetadataUtils;
3639
import com.google.devtools.build.lib.vfs.Path;
@@ -52,12 +55,14 @@
5255
import java.util.concurrent.CancellationException;
5356
import java.util.concurrent.Executor;
5457
import java.util.concurrent.atomic.AtomicBoolean;
58+
import java.util.regex.Pattern;
5559
import java.util.stream.Collectors;
5660
import javax.annotation.Nullable;
5761

5862
/** A {@link BuildEventArtifactUploader} backed by {@link RemoteCache}. */
5963
class ByteStreamBuildEventArtifactUploader extends AbstractReferenceCounted
6064
implements BuildEventArtifactUploader {
65+
private static final Pattern TEST_LOG_PATTERN = Pattern.compile(".*/bazel-out/[^/]*/testlogs/.*");
6166

6267
private final Executor executor;
6368
private final ExtendedEventHandler reporter;
@@ -73,6 +78,9 @@ class ByteStreamBuildEventArtifactUploader extends AbstractReferenceCounted
7378
private final Set<PathFragment> omittedFiles = Sets.newConcurrentHashSet();
7479
private final Set<PathFragment> omittedTreeRoots = Sets.newConcurrentHashSet();
7580
private final XattrProvider xattrProvider;
81+
private final RemoteBuildEventUploadMode remoteBuildEventUploadMode;
82+
83+
@Nullable private Path profilePath;
7684

7785
ByteStreamBuildEventArtifactUploader(
7886
Executor executor,
@@ -82,7 +90,8 @@ class ByteStreamBuildEventArtifactUploader extends AbstractReferenceCounted
8290
String remoteServerInstanceName,
8391
String buildRequestId,
8492
String commandId,
85-
XattrProvider xattrProvider) {
93+
XattrProvider xattrProvider,
94+
RemoteBuildEventUploadMode remoteBuildEventUploadMode) {
8695
this.executor = executor;
8796
this.reporter = reporter;
8897
this.verboseFailures = verboseFailures;
@@ -92,6 +101,7 @@ class ByteStreamBuildEventArtifactUploader extends AbstractReferenceCounted
92101
this.remoteServerInstanceName = remoteServerInstanceName;
93102
this.scheduler = Schedulers.from(executor);
94103
this.xattrProvider = xattrProvider;
104+
this.remoteBuildEventUploadMode = remoteBuildEventUploadMode;
95105
}
96106

97107
public void omitFile(Path file) {
@@ -197,8 +207,27 @@ private static void processQueryResult(
197207
}
198208
}
199209

200-
private static boolean shouldUpload(PathMetadata path) {
201-
return path.getDigest() != null && !path.isRemote() && !path.isDirectory() && !path.isOmitted();
210+
private boolean shouldQuery(PathMetadata path) {
211+
return path.getDigest() != null && !path.isRemote() && !path.isDirectory();
212+
}
213+
214+
private boolean shouldUpload(PathMetadata path) {
215+
boolean result =
216+
path.getDigest() != null && !path.isRemote() && !path.isDirectory() && !path.isOmitted();
217+
218+
if (remoteBuildEventUploadMode == RemoteBuildEventUploadMode.MINIMAL) {
219+
result = result && (isTestLog(path) || isProfile(path));
220+
}
221+
222+
return result;
223+
}
224+
225+
private boolean isTestLog(PathMetadata path) {
226+
return TEST_LOG_PATTERN.matcher(path.getPath().getPathString()).matches();
227+
}
228+
229+
private boolean isProfile(PathMetadata path) {
230+
return path.getPath().equals(profilePath);
202231
}
203232

204233
private Single<List<PathMetadata>> queryRemoteCache(
@@ -207,8 +236,7 @@ private Single<List<PathMetadata>> queryRemoteCache(
207236
List<PathMetadata> filesToQuery = new ArrayList<>();
208237
Set<Digest> digestsToQuery = new HashSet<>();
209238
for (PathMetadata path : paths) {
210-
// Query remote cache for files even if omitted from uploading
211-
if (shouldUpload(path) || path.isOmitted()) {
239+
if (shouldQuery(path)) {
212240
filesToQuery.add(path);
213241
digestsToQuery.add(path.getDigest());
214242
} else {
@@ -256,17 +284,20 @@ private Single<List<PathMetadata>> uploadLocalFiles(
256284
return toCompletable(
257285
() -> remoteCache.uploadFile(context, path.getDigest(), path.getPath()),
258286
executor)
259-
.toSingleDefault(path)
287+
.toSingle(
288+
() ->
289+
new PathMetadata(
290+
path.getPath(),
291+
path.getDigest(),
292+
path.isDirectory(),
293+
// set remote to true so the PathConverter will use bytestream://
294+
// scheme to convert the URI for this file
295+
/*remote=*/ true,
296+
path.isOmitted()))
260297
.onErrorResumeNext(
261298
error -> {
262299
reporterUploadError(error);
263-
return Single.just(
264-
new PathMetadata(
265-
path.getPath(),
266-
/*digest=*/ null,
267-
path.isDirectory(),
268-
path.isRemote(),
269-
path.isOmitted()));
300+
return Single.just(path);
270301
});
271302
})
272303
.collect(Collectors.toList());
@@ -308,6 +339,11 @@ private Single<PathConverter> upload(Set<Path> files) {
308339
RemoteCache::release);
309340
}
310341

342+
@Subscribe
343+
public void onProfilerStartedEvent(ProfilerStartedEvent event) {
344+
profilePath = event.getProfilePath();
345+
}
346+
311347
@Override
312348
public ListenableFuture<PathConverter> upload(Map<Path, LocalFile> files) {
313349
return toListenableFuture(upload(files.keySet()).subscribeOn(scheduler));
@@ -347,10 +383,12 @@ private static class PathConverterImpl implements PathConverter {
347383
for (PathMetadata pair : uploads) {
348384
Path path = pair.getPath();
349385
Digest digest = pair.getDigest();
350-
if (!pair.isRemote() && pair.isOmitted()) {
351-
localPaths.add(path);
352-
} else if (digest != null) {
353-
pathToDigest.put(path, digest);
386+
if (digest != null) {
387+
if (pair.isRemote()) {
388+
pathToDigest.put(path, digest);
389+
} else {
390+
localPaths.add(path);
391+
}
354392
} else {
355393
skippedPaths.add(path);
356394
}

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import com.google.devtools.build.lib.buildeventstream.BuildEventArtifactUploader;
1919
import com.google.devtools.build.lib.events.ExtendedEventHandler;
20+
import com.google.devtools.build.lib.remote.options.RemoteBuildEventUploadMode;
2021
import com.google.devtools.build.lib.runtime.BuildEventArtifactUploaderFactory;
2122
import com.google.devtools.build.lib.runtime.CommandEnvironment;
2223
import java.util.concurrent.Executor;
@@ -32,6 +33,7 @@ class ByteStreamBuildEventArtifactUploaderFactory implements BuildEventArtifactU
3233
private final String remoteServerInstanceName;
3334
private final String buildRequestId;
3435
private final String commandId;
36+
private final RemoteBuildEventUploadMode remoteBuildEventUploadMode;
3537

3638
@Nullable private ByteStreamBuildEventArtifactUploader uploader;
3739

@@ -42,14 +44,16 @@ class ByteStreamBuildEventArtifactUploaderFactory implements BuildEventArtifactU
4244
RemoteCache remoteCache,
4345
String remoteServerInstanceName,
4446
String buildRequestId,
45-
String commandId) {
47+
String commandId,
48+
RemoteBuildEventUploadMode remoteBuildEventUploadMode) {
4649
this.executor = executor;
4750
this.reporter = reporter;
4851
this.verboseFailures = verboseFailures;
4952
this.remoteCache = remoteCache;
5053
this.remoteServerInstanceName = remoteServerInstanceName;
5154
this.buildRequestId = buildRequestId;
5255
this.commandId = commandId;
56+
this.remoteBuildEventUploadMode = remoteBuildEventUploadMode;
5357
}
5458

5559
@Override
@@ -64,7 +68,9 @@ public BuildEventArtifactUploader create(CommandEnvironment env) {
6468
remoteServerInstanceName,
6569
buildRequestId,
6670
commandId,
67-
env.getXattrProvider());
71+
env.getXattrProvider(),
72+
remoteBuildEventUploadMode);
73+
env.getEventBus().register(uploader);
6874
return uploader;
6975
}
7076

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
import com.google.devtools.build.lib.remote.common.RemoteExecutionClient;
6969
import com.google.devtools.build.lib.remote.downloader.GrpcRemoteDownloader;
7070
import com.google.devtools.build.lib.remote.logging.LoggingInterceptor;
71+
import com.google.devtools.build.lib.remote.options.RemoteBuildEventUploadMode;
7172
import com.google.devtools.build.lib.remote.options.RemoteOptions;
7273
import com.google.devtools.build.lib.remote.options.RemoteOutputsMode;
7374
import com.google.devtools.build.lib.remote.util.DigestUtil;
@@ -650,7 +651,8 @@ public void beforeCommand(CommandEnvironment env) throws AbruptExitException {
650651
actionContextProvider.getRemoteCache(),
651652
remoteBytestreamUriPrefix,
652653
buildRequestId,
653-
invocationId));
654+
invocationId,
655+
remoteOptions.remoteBuildEventUploadMode));
654656

655657
if (enableRemoteDownloader) {
656658
Downloader fallbackDownloader = null;
@@ -754,7 +756,9 @@ public void afterAnalysis(
754756
actionContextProvider.setFilesToDownload(ImmutableSet.copyOf(filesToDownload));
755757
}
756758

757-
if (remoteOptions != null && remoteOptions.incompatibleRemoteBuildEventUploadRespectNoCache) {
759+
if (remoteOptions != null
760+
&& remoteOptions.remoteBuildEventUploadMode == RemoteBuildEventUploadMode.ALL
761+
&& remoteOptions.incompatibleRemoteBuildEventUploadRespectNoCache) {
758762
parseNoCacheOutputs(analysisResult);
759763
}
760764
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2022 The Bazel Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
package com.google.devtools.build.lib.remote.options;
15+
16+
/** Describes how to upload local files referenced in BEP to remote cache. */
17+
public enum RemoteBuildEventUploadMode {
18+
// Uploads all local files to remote cache.
19+
ALL,
20+
// Only upload important local files (e.g. test logs, timing profile) to remote cache.
21+
MINIMAL,
22+
}

src/main/java/com/google/devtools/build/lib/remote/options/RemoteOptions.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,16 +276,44 @@ public String getTypeDescription() {
276276
help = "Whether to upload locally executed action results to the remote cache.")
277277
public boolean remoteUploadLocalResults;
278278

279+
@Deprecated
279280
@Option(
280281
name = "incompatible_remote_build_event_upload_respect_no_cache",
281282
defaultValue = "false",
282283
documentationCategory = OptionDocumentationCategory.REMOTE,
283284
effectTags = {OptionEffectTag.UNKNOWN},
285+
deprecationWarning =
286+
"--incompatible_remote_build_event_upload_respect_no_cache has been deprecated in favor"
287+
+ " of --experimental_remote_build_event_upload=minimal.",
284288
help =
285289
"If set to true, outputs referenced by BEP are not uploaded to remote cache if the"
286290
+ " generating action cannot be cached remotely.")
287291
public boolean incompatibleRemoteBuildEventUploadRespectNoCache;
288292

293+
@Option(
294+
name = "experimental_remote_build_event_upload",
295+
defaultValue = "all",
296+
documentationCategory = OptionDocumentationCategory.REMOTE,
297+
effectTags = {OptionEffectTag.UNKNOWN},
298+
converter = RemoteBuildEventUploadModeConverter.class,
299+
help =
300+
"If set to 'all', all local outputs referenced by BEP are uploaded to remote cache.\n"
301+
+ "If set to 'minimal', local outputs referenced by BEP are not uploaded to the"
302+
+ " remote cache, except for files that are important to the consumers of BEP (e.g."
303+
+ " test logs and timing profile).\n"
304+
+ "file:// scheme is used for the paths of local files and bytestream:// scheme is"
305+
+ " used for the paths of (already) uploaded files.\n"
306+
+ "Default to 'all'.")
307+
public RemoteBuildEventUploadMode remoteBuildEventUploadMode;
308+
309+
/** Build event upload mode flag parser */
310+
public static class RemoteBuildEventUploadModeConverter
311+
extends EnumConverter<RemoteBuildEventUploadMode> {
312+
public RemoteBuildEventUploadModeConverter() {
313+
super(RemoteBuildEventUploadMode.class, "remote build event upload");
314+
}
315+
}
316+
289317
@Option(
290318
name = "incompatible_remote_results_ignore_disk",
291319
defaultValue = "true",

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import com.google.devtools.build.lib.remote.common.MissingDigestsFinder;
5454
import com.google.devtools.build.lib.remote.common.RemoteActionExecutionContext;
5555
import com.google.devtools.build.lib.remote.grpc.ChannelConnectionFactory;
56+
import com.google.devtools.build.lib.remote.options.RemoteBuildEventUploadMode;
5657
import com.google.devtools.build.lib.remote.options.RemoteOptions;
5758
import com.google.devtools.build.lib.remote.util.DigestUtil;
5859
import com.google.devtools.build.lib.remote.util.RxNoGlobalErrorsRule;
@@ -481,7 +482,8 @@ private ByteStreamBuildEventArtifactUploader newArtifactUploader(RemoteCache rem
481482
/*remoteServerInstanceName=*/ "localhost/instance",
482483
/*buildRequestId=*/ "none",
483484
/*commandId=*/ "none",
484-
SyscallCache.NO_CACHE);
485+
SyscallCache.NO_CACHE,
486+
RemoteBuildEventUploadMode.ALL);
485487
}
486488

487489
private static class StaticMissingDigestsFinder implements MissingDigestsFinder {

src/test/shell/bazel/remote/BUILD

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,14 @@ sh_test(
117117
"@bazel_tools//tools/bash/runfiles",
118118
],
119119
)
120+
121+
sh_test(
122+
name = "remote_build_event_uploader_test",
123+
srcs = ["remote_build_event_uploader_test.sh"],
124+
data = [
125+
":remote_utils",
126+
"//src/test/shell/bazel:test-deps",
127+
"//src/tools/remote:worker",
128+
"@bazel_tools//tools/bash/runfiles",
129+
],
130+
)

0 commit comments

Comments
 (0)