blob: 51a1d6590357842328e2454a4841e42655aa715d [file] [log] [blame]
ulfjack9274cba2017-08-11 23:19:48 +02001// Copyright 2017 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.
14package com.google.devtools.build.lib.remote;
15
Jakob Buchgraber321138f2018-05-07 05:24:53 -070016import static com.google.common.base.Strings.isNullOrEmpty;
buchgrd480c5f2019-04-03 00:53:34 -070017import static com.google.devtools.build.lib.remote.util.Utils.createSpawnResult;
18import static com.google.devtools.build.lib.remote.util.Utils.getInMemoryOutputPath;
Jakob Buchgraber11a98a52019-09-02 07:57:02 -070019import static com.google.devtools.build.lib.remote.util.Utils.hasFilesToDownload;
Jakob Buchgraber50c10042019-04-11 02:11:19 -070020import static com.google.devtools.build.lib.remote.util.Utils.shouldDownloadAllSpawnOutputs;
Jakob Buchgraber321138f2018-05-07 05:24:53 -070021
olaolaf0aa55d2018-08-16 08:51:06 -070022import build.bazel.remote.execution.v2.Action;
23import build.bazel.remote.execution.v2.ActionResult;
24import build.bazel.remote.execution.v2.Command;
buchgr7f725442019-03-08 03:20:25 -080025import build.bazel.remote.execution.v2.Digest;
John Cater3afb7b02019-01-18 11:44:51 -080026import build.bazel.remote.execution.v2.Platform;
Jakob Buchgraber50c10042019-04-11 02:11:19 -070027import com.google.common.base.Preconditions;
George Gensure7aa74982020-04-01 00:54:15 -070028import com.google.common.base.Stopwatch;
George Gensure54b062c2020-09-02 05:06:40 -070029import com.google.common.base.Throwables;
Jakob Buchgraber50c10042019-04-11 02:11:19 -070030import com.google.common.collect.ImmutableSet;
ulfjack9274cba2017-08-11 23:19:48 +020031import com.google.devtools.build.lib.actions.ActionInput;
32import com.google.devtools.build.lib.actions.ExecException;
shahan602cc852018-06-06 20:09:57 -070033import com.google.devtools.build.lib.actions.FileArtifactValue;
ulfjack9274cba2017-08-11 23:19:48 +020034import com.google.devtools.build.lib.actions.Spawn;
George Gensure7aa74982020-04-01 00:54:15 -070035import com.google.devtools.build.lib.actions.SpawnMetrics;
rupertsda40fbf2017-09-22 05:59:42 +020036import com.google.devtools.build.lib.actions.SpawnResult;
37import com.google.devtools.build.lib.actions.SpawnResult.Status;
olaolaa22d0e92017-12-11 07:53:15 -080038import com.google.devtools.build.lib.actions.Spawns;
Mike Moreartyd8ac06a2018-04-12 01:59:34 -070039import com.google.devtools.build.lib.actions.cache.VirtualActionInput;
Googler77ef8d62019-07-23 11:55:53 -070040import com.google.devtools.build.lib.analysis.platform.PlatformUtils;
ulfjack9274cba2017-08-11 23:19:48 +020041import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
Benjamin Peterson3ff87f72017-08-21 18:41:45 +020042import com.google.devtools.build.lib.events.Event;
43import com.google.devtools.build.lib.events.Reporter;
ulfjack9274cba2017-08-11 23:19:48 +020044import com.google.devtools.build.lib.exec.SpawnCache;
Benjamin Peterson7e1c7bc2018-05-03 04:30:19 -070045import com.google.devtools.build.lib.exec.SpawnRunner.ProgressStatus;
tomlu29e306d2018-04-19 05:41:44 -070046import com.google.devtools.build.lib.exec.SpawnRunner.SpawnExecutionContext;
ulfjack5f436f32018-11-06 05:17:23 -080047import com.google.devtools.build.lib.profiler.Profiler;
Jakob Buchgraber4b3c2eb2019-04-04 02:01:48 -070048import com.google.devtools.build.lib.profiler.ProfilerTask;
ulfjack5f436f32018-11-06 05:17:23 -080049import com.google.devtools.build.lib.profiler.SilentCloseable;
Jakob Buchgraber18462692019-11-06 04:34:16 -080050import com.google.devtools.build.lib.remote.common.CacheNotFoundException;
Jakob Buchgraber60566092019-11-11 06:28:22 -080051import com.google.devtools.build.lib.remote.common.RemoteCacheClient.ActionKey;
buchgr7f725442019-03-08 03:20:25 -080052import com.google.devtools.build.lib.remote.merkletree.MerkleTree;
Jakob Buchgraber75b7ed42019-03-27 10:27:13 -070053import com.google.devtools.build.lib.remote.options.RemoteOptions;
buchgrd480c5f2019-04-03 00:53:34 -070054import com.google.devtools.build.lib.remote.options.RemoteOutputsMode;
Googler922d1e62018-03-05 14:49:00 -080055import com.google.devtools.build.lib.remote.util.DigestUtil;
George Gensure7aa74982020-04-01 00:54:15 -070056import com.google.devtools.build.lib.remote.util.NetworkTime;
Googler922d1e62018-03-05 14:49:00 -080057import com.google.devtools.build.lib.remote.util.TracingMetadataUtils;
Jakob Buchgrabera79a4b62019-06-23 02:06:20 -070058import com.google.devtools.build.lib.remote.util.Utils;
buchgrd480c5f2019-04-03 00:53:34 -070059import com.google.devtools.build.lib.remote.util.Utils.InMemoryOutput;
ulfjack9274cba2017-08-11 23:19:48 +020060import com.google.devtools.build.lib.vfs.Path;
61import com.google.devtools.build.lib.vfs.PathFragment;
olaola6f32d5a2017-09-20 17:12:19 +020062import io.grpc.Context;
ulfjack9274cba2017-08-11 23:19:48 +020063import java.io.IOException;
64import java.util.Collection;
Jakob Buchgraber321138f2018-05-07 05:24:53 -070065import java.util.HashSet;
ulfjack9274cba2017-08-11 23:19:48 +020066import java.util.NoSuchElementException;
Jakob Buchgraber321138f2018-05-07 05:24:53 -070067import java.util.Set;
ulfjack9274cba2017-08-11 23:19:48 +020068import java.util.SortedMap;
Benjamin Peterson3ff87f72017-08-21 18:41:45 +020069import javax.annotation.Nullable;
ulfjack9274cba2017-08-11 23:19:48 +020070
Jakob Buchgraber321138f2018-05-07 05:24:53 -070071/** A remote {@link SpawnCache} implementation. */
ulfjack9274cba2017-08-11 23:19:48 +020072@ThreadSafe // If the RemoteActionCache implementation is thread-safe.
ulfjack9274cba2017-08-11 23:19:48 +020073final class RemoteSpawnCache implements SpawnCache {
Jakob Buchgraber50c10042019-04-11 02:11:19 -070074
ulfjack9274cba2017-08-11 23:19:48 +020075 private final Path execRoot;
76 private final RemoteOptions options;
George Gensure54b062c2020-09-02 05:06:40 -070077 private final boolean verboseFailures;
ulfjack9274cba2017-08-11 23:19:48 +020078
Jakob Buchgraber60566092019-11-11 06:28:22 -080079 private final RemoteCache remoteCache;
olaola6f32d5a2017-09-20 17:12:19 +020080 private final String buildRequestId;
81 private final String commandId;
ulfjack9274cba2017-08-11 23:19:48 +020082
Benjamin Peterson3ff87f72017-08-21 18:41:45 +020083 @Nullable private final Reporter cmdlineReporter;
84
Jakob Buchgraber321138f2018-05-07 05:24:53 -070085 private final Set<String> reportedErrors = new HashSet<>();
Benjamin Peterson3ff87f72017-08-21 18:41:45 +020086
buchgr559a07d2017-11-30 11:09:35 -080087 private final DigestUtil digestUtil;
88
Jakob Buchgraber50c10042019-04-11 02:11:19 -070089 /**
Jakob Buchgraber11a98a52019-09-02 07:57:02 -070090 * If {@link RemoteOutputsMode#TOPLEVEL} is specified it contains the artifacts that should be
91 * downloaded.
Jakob Buchgraber50c10042019-04-11 02:11:19 -070092 */
Jakob Buchgraber11a98a52019-09-02 07:57:02 -070093 private final ImmutableSet<ActionInput> filesToDownload;
Jakob Buchgraber50c10042019-04-11 02:11:19 -070094
olaola6f32d5a2017-09-20 17:12:19 +020095 RemoteSpawnCache(
96 Path execRoot,
97 RemoteOptions options,
George Gensure54b062c2020-09-02 05:06:40 -070098 boolean verboseFailures,
Jakob Buchgraber60566092019-11-11 06:28:22 -080099 RemoteCache remoteCache,
olaola6f32d5a2017-09-20 17:12:19 +0200100 String buildRequestId,
101 String commandId,
buchgr559a07d2017-11-30 11:09:35 -0800102 @Nullable Reporter cmdlineReporter,
Jakob Buchgraber50c10042019-04-11 02:11:19 -0700103 DigestUtil digestUtil,
Jakob Buchgraber11a98a52019-09-02 07:57:02 -0700104 ImmutableSet<ActionInput> filesToDownload) {
ulfjack9274cba2017-08-11 23:19:48 +0200105 this.execRoot = execRoot;
106 this.options = options;
George Gensure54b062c2020-09-02 05:06:40 -0700107 this.verboseFailures = verboseFailures;
ulfjack9274cba2017-08-11 23:19:48 +0200108 this.remoteCache = remoteCache;
Benjamin Peterson3ff87f72017-08-21 18:41:45 +0200109 this.cmdlineReporter = cmdlineReporter;
olaola6f32d5a2017-09-20 17:12:19 +0200110 this.buildRequestId = buildRequestId;
111 this.commandId = commandId;
buchgr559a07d2017-11-30 11:09:35 -0800112 this.digestUtil = digestUtil;
Jakob Buchgraber11a98a52019-09-02 07:57:02 -0700113 this.filesToDownload = Preconditions.checkNotNull(filesToDownload, "filesToDownload");
ulfjack9274cba2017-08-11 23:19:48 +0200114 }
115
116 @Override
tomlu29e306d2018-04-19 05:41:44 -0700117 public CacheHandle lookup(Spawn spawn, SpawnExecutionContext context)
ulfjack9274cba2017-08-11 23:19:48 +0200118 throws InterruptedException, IOException, ExecException {
Sergio Rodriguez Orellana8860c3e2019-07-25 01:12:58 -0700119 if (!Spawns.mayBeCached(spawn)
Bor Kae Hwang9c0cab42019-12-19 06:39:10 -0800120 || (!Spawns.mayBeCachedRemotely(spawn) && useRemoteCache(options))) {
Sergio Rodriguez Orellana8860c3e2019-07-25 01:12:58 -0700121 // returning SpawnCache.NO_RESULT_NO_STORE in case the caching is disabled or in case
122 // the remote caching is disabled and the only configured cache is remote.
Benjamin Petersonf1570532019-01-24 07:14:18 -0800123 return SpawnCache.NO_RESULT_NO_STORE;
124 }
Benjamin Peterson7e1c7bc2018-05-03 04:30:19 -0700125
George Gensure7aa74982020-04-01 00:54:15 -0700126 NetworkTime networkTime = new NetworkTime();
127 Stopwatch totalTime = Stopwatch.createStarted();
128
twerthc4dfb912020-07-20 10:32:42 -0700129 SortedMap<PathFragment, ActionInput> inputMap = context.getInputMapping();
buchgr7f725442019-03-08 03:20:25 -0800130 MerkleTree merkleTree =
131 MerkleTree.build(inputMap, context.getMetadataProvider(), execRoot, digestUtil);
George Gensure7aa74982020-04-01 00:54:15 -0700132 SpawnMetrics.Builder spawnMetrics =
Googler2b7e71a2020-06-04 01:32:01 -0700133 SpawnMetrics.Builder.forRemoteExec()
George Gensure7aa74982020-04-01 00:54:15 -0700134 .setInputBytes(merkleTree.getInputBytes())
135 .setInputFiles(merkleTree.getInputFiles());
buchgr7f725442019-03-08 03:20:25 -0800136 Digest merkleTreeRoot = merkleTree.getRootDigest();
John Cater3afb7b02019-01-18 11:44:51 -0800137
138 // Get the remote platform properties.
Googler0dc53a22019-08-25 22:09:56 -0700139 Platform platform = PlatformUtils.getPlatformProto(spawn, options);
John Cater3afb7b02019-01-18 11:44:51 -0800140
olaolaf0aa55d2018-08-16 08:51:06 -0700141 Command command =
142 RemoteSpawnRunner.buildCommand(
buchgr06a26c32019-11-20 02:01:12 -0800143 spawn.getOutputFiles(),
144 spawn.getArguments(),
145 spawn.getEnvironment(),
146 platform,
147 /* workingDirectory= */ null);
buchgrd480c5f2019-04-03 00:53:34 -0700148 RemoteOutputsMode remoteOutputsMode = options.remoteOutputsMode;
Jakob Buchgraber54d7d612019-03-25 08:30:17 -0700149 Action action =
150 RemoteSpawnRunner.buildAction(
151 digestUtil.compute(command), merkleTreeRoot, context.getTimeout(), true);
152 // Look up action cache, and reuse the action output if it is found.
153 ActionKey actionKey = digestUtil.computeActionKey(action);
olaola6f32d5a2017-09-20 17:12:19 +0200154 Context withMetadata =
George Gensure7aa74982020-04-01 00:54:15 -0700155 TracingMetadataUtils.contextWithMetadata(buildRequestId, commandId, actionKey)
156 .withValue(NetworkTime.CONTEXT_KEY, networkTime);
Benjamin Peterson7e1c7bc2018-05-03 04:30:19 -0700157
Jakob Buchgraber4b3c2eb2019-04-04 02:01:48 -0700158 Profiler prof = Profiler.instance();
Bor Kae Hwang9c0cab42019-12-19 06:39:10 -0800159 if (options.remoteAcceptCached
160 || (options.incompatibleRemoteResultsIgnoreDisk && useDiskCache(options))) {
161 context.report(ProgressStatus.CHECKING_CACHE, "remote-cache");
Benjamin Peterson7e1c7bc2018-05-03 04:30:19 -0700162 // Metadata will be available in context.current() until we detach.
163 // This is done via a thread-local variable.
164 Context previous = withMetadata.attach();
165 try {
ulfjack5f436f32018-11-06 05:17:23 -0800166 ActionResult result;
Jakob Buchgraber4b3c2eb2019-04-04 02:01:48 -0700167 try (SilentCloseable c = prof.profile(ProfilerTask.REMOTE_CACHE_CHECK, "check cache hit")) {
Jakob Buchgraber21577f22020-03-23 03:11:29 -0700168 result = remoteCache.downloadActionResult(actionKey, /* inlineOutErr= */ false);
ulfjack5f436f32018-11-06 05:17:23 -0800169 }
Jakob Buchgraber50c10042019-04-11 02:11:19 -0700170 // In case the remote cache returned a failed action (exit code != 0) we treat it as a
171 // cache miss
ishikhman62f54582019-03-18 03:42:42 -0700172 if (result != null && result.getExitCode() == 0) {
buchgrd480c5f2019-04-03 00:53:34 -0700173 InMemoryOutput inMemoryOutput = null;
Jakob Buchgraber50c10042019-04-11 02:11:19 -0700174 boolean downloadOutputs =
175 shouldDownloadAllSpawnOutputs(
176 remoteOutputsMode,
177 /* exitCode = */ 0,
Jakob Buchgraber11a98a52019-09-02 07:57:02 -0700178 hasFilesToDownload(spawn.getOutputFiles(), filesToDownload));
George Gensure7aa74982020-04-01 00:54:15 -0700179 Stopwatch fetchTime = Stopwatch.createStarted();
Jakob Buchgraber50c10042019-04-11 02:11:19 -0700180 if (downloadOutputs) {
181 try (SilentCloseable c =
182 prof.profile(ProfilerTask.REMOTE_DOWNLOAD, "download outputs")) {
Jakob Buchgraberd75b6cf2019-06-19 08:12:49 -0700183 remoteCache.download(
184 result, execRoot, context.getFileOutErr(), context::lockOutputFiles);
Jakob Buchgraber50c10042019-04-11 02:11:19 -0700185 }
186 } else {
187 PathFragment inMemoryOutputPath = getInMemoryOutputPath(spawn);
188 // inject output metadata
189 try (SilentCloseable c =
190 prof.profile(ProfilerTask.REMOTE_DOWNLOAD, "download outputs minimal")) {
191 inMemoryOutput =
192 remoteCache.downloadMinimal(
George Gensure3ef8fb92020-05-06 09:49:48 -0700193 actionKey.getDigest().getHash(),
Jakob Buchgraber50c10042019-04-11 02:11:19 -0700194 result,
195 spawn.getOutputFiles(),
196 inMemoryOutputPath,
197 context.getFileOutErr(),
198 execRoot,
Jakob Buchgraberd75b6cf2019-06-19 08:12:49 -0700199 context.getMetadataInjector(),
200 context::lockOutputFiles);
Jakob Buchgraber50c10042019-04-11 02:11:19 -0700201 }
ulfjack5f436f32018-11-06 05:17:23 -0800202 }
George Gensure7aa74982020-04-01 00:54:15 -0700203 fetchTime.stop();
204 totalTime.stop();
205 spawnMetrics
206 .setFetchTime(fetchTime.elapsed())
207 .setTotalTime(totalTime.elapsed())
208 .setNetworkTime(networkTime.getDuration());
Benjamin Peterson7e1c7bc2018-05-03 04:30:19 -0700209 SpawnResult spawnResult =
buchgrd480c5f2019-04-03 00:53:34 -0700210 createSpawnResult(
George Gensure7aa74982020-04-01 00:54:15 -0700211 result.getExitCode(),
janakrf8dc2eb2020-09-30 08:06:53 -0700212 /*cacheHit=*/ true,
George Gensure7aa74982020-04-01 00:54:15 -0700213 "remote",
214 inMemoryOutput,
janakrf8dc2eb2020-09-30 08:06:53 -0700215 spawnMetrics.build(),
216 spawn.getMnemonic());
Benjamin Peterson7e1c7bc2018-05-03 04:30:19 -0700217 return SpawnCache.success(spawnResult);
218 }
Benjamin Peterson1532df02019-01-24 08:45:44 -0800219 } catch (CacheNotFoundException e) {
220 // Intentionally left blank
Benjamin Peterson7e1c7bc2018-05-03 04:30:19 -0700221 } catch (IOException e) {
George Gensure54b062c2020-09-02 05:06:40 -0700222 if (BulkTransferException.isOnlyCausedByCacheNotFoundException(e)) {
223 // Intentionally left blank
224 } else {
225 String errorMessage;
226 if (!verboseFailures) {
227 errorMessage = Utils.grpcAwareErrorMessage(e);
228 } else {
229 // On --verbose_failures print the whole stack trace
230 errorMessage = Throwables.getStackTraceAsString(e);
231 }
232 if (isNullOrEmpty(errorMessage)) {
233 errorMessage = e.getClass().getSimpleName();
234 }
235 errorMessage = "Reading from Remote Cache:\n" + errorMessage;
236 report(Event.warn(errorMessage));
Benjamin Peterson1532df02019-01-24 08:45:44 -0800237 }
Benjamin Peterson7e1c7bc2018-05-03 04:30:19 -0700238 } finally {
239 withMetadata.detach(previous);
ulfjack9274cba2017-08-11 23:19:48 +0200240 }
ulfjack9274cba2017-08-11 23:19:48 +0200241 }
buchgrd480c5f2019-04-03 00:53:34 -0700242
243 context.prefetchInputs();
244
Bor Kae Hwang9c0cab42019-12-19 06:39:10 -0800245 if (options.remoteUploadLocalResults
246 || (options.incompatibleRemoteResultsIgnoreDisk && useDiskCache(options))) {
olaolaba8b0b32017-10-20 09:48:56 +0200247 return new CacheHandle() {
248 @Override
249 public boolean hasResult() {
250 return false;
251 }
252
253 @Override
254 public SpawnResult getResult() {
255 throw new NoSuchElementException();
256 }
257
258 @Override
259 public boolean willStore() {
260 return true;
261 }
262
263 @Override
Jakob Buchgraberbac30fe2019-01-28 05:24:23 -0800264 public void store(SpawnResult result) throws ExecException, InterruptedException {
265 boolean uploadResults = Status.SUCCESS.equals(result.status()) && result.exitCode() == 0;
266 if (!uploadResults) {
267 return;
268 }
269
ulfjack8896d2e2018-01-19 02:55:21 -0800270 if (options.experimentalGuardAgainstConcurrentChanges) {
Jakob Buchgraber4b3c2eb2019-04-04 02:01:48 -0700271 try (SilentCloseable c = prof.profile("RemoteCache.checkForConcurrentModifications")) {
ulfjack8896d2e2018-01-19 02:55:21 -0800272 checkForConcurrentModifications();
273 } catch (IOException e) {
274 report(Event.warn(e.getMessage()));
275 return;
276 }
277 }
Jakob Buchgraberbac30fe2019-01-28 05:24:23 -0800278
olaolaba8b0b32017-10-20 09:48:56 +0200279 Context previous = withMetadata.attach();
Benjamin Petersondd3ddb02018-05-03 09:20:08 -0700280 Collection<Path> files =
281 RemoteSpawnRunner.resolveActionInputs(execRoot, spawn.getOutputFiles());
Jakob Buchgraber4b3c2eb2019-04-04 02:01:48 -0700282 try (SilentCloseable c = prof.profile(ProfilerTask.UPLOAD_TIME, "upload outputs")) {
olaolaf0aa55d2018-08-16 08:51:06 -0700283 remoteCache.upload(
Jakob Buchgraberbac30fe2019-01-28 05:24:23 -0800284 actionKey, action, command, execRoot, files, context.getFileOutErr());
olaolaba8b0b32017-10-20 09:48:56 +0200285 } catch (IOException e) {
George Gensure54b062c2020-09-02 05:06:40 -0700286 String errorMessage;
287 if (!verboseFailures) {
288 errorMessage = Utils.grpcAwareErrorMessage(e);
289 } else {
290 // On --verbose_failures print the whole stack trace
291 errorMessage = Throwables.getStackTraceAsString(e);
olaolaba8b0b32017-10-20 09:48:56 +0200292 }
George Gensure54b062c2020-09-02 05:06:40 -0700293 if (isNullOrEmpty(errorMessage)) {
294 errorMessage = e.getClass().getSimpleName();
295 }
296 errorMessage = "Writing to Remote Cache:\n" + errorMessage;
297 report(Event.warn(errorMessage));
olaolaba8b0b32017-10-20 09:48:56 +0200298 } finally {
299 withMetadata.detach(previous);
300 }
301 }
302
303 @Override
304 public void close() {}
ulfjack8896d2e2018-01-19 02:55:21 -0800305
306 private void checkForConcurrentModifications() throws IOException {
307 for (ActionInput input : inputMap.values()) {
Mike Moreartyd8ac06a2018-04-12 01:59:34 -0700308 if (input instanceof VirtualActionInput) {
309 continue;
310 }
shahan499503b2018-06-07 18:57:07 -0700311 FileArtifactValue metadata = context.getMetadataProvider().getMetadata(input);
olaolaf0aa55d2018-08-16 08:51:06 -0700312 Path path = execRoot.getRelative(input.getExecPath());
313 if (metadata.wasModifiedSinceDigest(path)) {
314 throw new IOException(path + " was modified during execution");
ulfjack8896d2e2018-01-19 02:55:21 -0800315 }
316 }
317 }
olaolaba8b0b32017-10-20 09:48:56 +0200318 };
319 } else {
320 return SpawnCache.NO_RESULT_NO_STORE;
321 }
ulfjack9274cba2017-08-11 23:19:48 +0200322 }
Benjamin Peterson3ff87f72017-08-21 18:41:45 +0200323
Benjamin Peterson3ff87f72017-08-21 18:41:45 +0200324 private void report(Event evt) {
Jakob Buchgraber321138f2018-05-07 05:24:53 -0700325 if (cmdlineReporter == null) {
326 return;
327 }
328
329 synchronized (this) {
330 if (reportedErrors.contains(evt.getMessage())) {
331 return;
332 }
333 reportedErrors.add(evt.getMessage());
Benjamin Peterson3ff87f72017-08-21 18:41:45 +0200334 cmdlineReporter.handle(evt);
335 }
336 }
Sergio Rodriguez Orellana8860c3e2019-07-25 01:12:58 -0700337
Bor Kae Hwang9c0cab42019-12-19 06:39:10 -0800338 private static boolean useRemoteCache(RemoteOptions options) {
Josh Smith33d0a1c2020-05-05 07:42:37 -0700339 return !isNullOrEmpty(options.remoteCache) || !isNullOrEmpty(options.remoteExecutor);
Sergio Rodriguez Orellana8860c3e2019-07-25 01:12:58 -0700340 }
Bor Kae Hwang9c0cab42019-12-19 06:39:10 -0800341
342 private static boolean useDiskCache(RemoteOptions options) {
343 return options.diskCache != null && !options.diskCache.isEmpty();
344 }
larsrc02838a12020-11-10 03:46:53 -0800345
346 @Override
347 public boolean usefulInDynamicExecution() {
348 return false;
349 }
ulfjack9274cba2017-08-11 23:19:48 +0200350}