blob: d382364cd1fdc9313bd15e0b2227ba3fa69cd9c7 [file] [log] [blame]
Alpha Lam79adf592016-02-10 15:38:59 +00001// Copyright 2016 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.
Alpha Lam79adf592016-02-10 15:38:59 +000014package com.google.devtools.build.lib.remote;
15
buchgrbcbd2da2017-07-14 14:58:07 +020016import static com.google.common.base.Preconditions.checkNotNull;
chiwang581c81a2021-09-06 19:00:55 -070017import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
buchgrbcbd2da2017-07-14 14:58:07 +020018
philwod6ce2642018-07-30 05:24:50 -070019import com.google.common.base.Preconditions;
Jakob Buchgraber50c10042019-04-11 02:11:19 -070020import com.google.common.collect.ImmutableSet;
Jakob Buchgraber20342c72019-11-12 04:56:16 -080021import com.google.common.util.concurrent.ListeningScheduledExecutorService;
Jakob Buchgraber34784c32019-07-22 07:40:14 -070022import com.google.devtools.build.lib.actions.ActionInput;
Alpha Lam79adf592016-02-10 15:38:59 +000023import com.google.devtools.build.lib.exec.ExecutionOptions;
jcater1d09f572020-03-31 04:44:27 -070024import com.google.devtools.build.lib.exec.ModuleActionContextRegistry;
schmittf8f59bc2020-01-15 10:05:18 -080025import com.google.devtools.build.lib.exec.SpawnCache;
jcater1d09f572020-03-31 04:44:27 -070026import com.google.devtools.build.lib.exec.SpawnStrategyRegistry;
Chi Wangb863dbf2021-04-19 00:55:59 -070027import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions;
Chi Wang09d8f142020-10-30 01:03:16 -070028import com.google.devtools.build.lib.remote.common.RemoteExecutionClient;
Chi Wangb863dbf2021-04-19 00:55:59 -070029import com.google.devtools.build.lib.remote.common.RemotePathResolver;
30import com.google.devtools.build.lib.remote.common.RemotePathResolver.DefaultRemotePathResolver;
31import com.google.devtools.build.lib.remote.common.RemotePathResolver.SiblingRepositoryLayoutResolver;
Jakob Buchgraber75b7ed42019-03-27 10:27:13 -070032import com.google.devtools.build.lib.remote.options.RemoteOptions;
Googler922d1e62018-03-05 14:49:00 -080033import com.google.devtools.build.lib.remote.util.DigestUtil;
Chi Wang621649d2022-01-26 02:14:29 -080034import com.google.devtools.build.lib.runtime.BlockWaitingModule;
Alpha Lam79adf592016-02-10 15:38:59 +000035import com.google.devtools.build.lib.runtime.CommandEnvironment;
olaolabf326fa2018-03-21 11:22:12 -070036import com.google.devtools.build.lib.vfs.Path;
chiwang581c81a2021-09-06 19:00:55 -070037import java.util.concurrent.Executor;
buchgrbcbd2da2017-07-14 14:58:07 +020038import javax.annotation.Nullable;
Alpha Lam79adf592016-02-10 15:38:59 +000039
jhorvitzcd477f22021-05-05 10:18:22 -070040/** Provides a remote execution context. */
chiwang7f08b782021-09-05 21:04:35 -070041final class RemoteActionContextProvider {
schmitt1bbb1e12020-01-17 08:14:14 -080042
chiwang581c81a2021-09-06 19:00:55 -070043 private final Executor executor;
ulfjackacd291a2017-06-16 15:25:42 +020044 private final CommandEnvironment env;
chiwang581c81a2021-09-06 19:00:55 -070045 @Nullable private final RemoteCache remoteCache;
46 @Nullable private final RemoteExecutionClient remoteExecutor;
Jakob Buchgraber6bcdf112019-11-13 06:53:55 -080047 @Nullable private final ListeningScheduledExecutorService retryScheduler;
buchgr559a07d2017-11-30 11:09:35 -080048 private final DigestUtil digestUtil;
Jakob Buchgraber716e4e32019-01-21 07:59:23 -080049 @Nullable private final Path logDir;
Jakob Buchgraber11a98a52019-09-02 07:57:02 -070050 private ImmutableSet<ActionInput> filesToDownload = ImmutableSet.of();
chiwangae539912021-04-23 00:25:02 -070051 private RemoteExecutionService remoteExecutionService;
buchgrbcbd2da2017-07-14 14:58:07 +020052
Jakob Buchgraber716e4e32019-01-21 07:59:23 -080053 private RemoteActionContextProvider(
chiwang581c81a2021-09-06 19:00:55 -070054 Executor executor,
buchgr559a07d2017-11-30 11:09:35 -080055 CommandEnvironment env,
chiwang581c81a2021-09-06 19:00:55 -070056 @Nullable RemoteCache remoteCache,
57 @Nullable RemoteExecutionClient remoteExecutor,
Jakob Buchgraber20342c72019-11-12 04:56:16 -080058 @Nullable ListeningScheduledExecutorService retryScheduler,
olaolabf326fa2018-03-21 11:22:12 -070059 DigestUtil digestUtil,
Jakob Buchgraber716e4e32019-01-21 07:59:23 -080060 @Nullable Path logDir) {
buchgrbcbd2da2017-07-14 14:58:07 +020061 this.executor = executor;
chiwang581c81a2021-09-06 19:00:55 -070062 this.env = Preconditions.checkNotNull(env, "env");
63 this.remoteCache = remoteCache;
64 this.remoteExecutor = remoteExecutor;
Jakob Buchgraber20342c72019-11-12 04:56:16 -080065 this.retryScheduler = retryScheduler;
buchgr559a07d2017-11-30 11:09:35 -080066 this.digestUtil = digestUtil;
olaolabf326fa2018-03-21 11:22:12 -070067 this.logDir = logDir;
Alpha Lam79adf592016-02-10 15:38:59 +000068 }
69
Chi Wang7643d3a2021-06-09 00:29:55 -070070 public static RemoteActionContextProvider createForPlaceholder(
71 CommandEnvironment env,
72 ListeningScheduledExecutorService retryScheduler,
73 DigestUtil digestUtil) {
74 return new RemoteActionContextProvider(
chiwang581c81a2021-09-06 19:00:55 -070075 directExecutor(),
76 env,
77 /*remoteCache=*/ null,
78 /*remoteExecutor=*/ null,
79 retryScheduler,
80 digestUtil,
81 /*logDir=*/ null);
Chi Wang7643d3a2021-06-09 00:29:55 -070082 }
83
Jakob Buchgraber716e4e32019-01-21 07:59:23 -080084 public static RemoteActionContextProvider createForRemoteCaching(
chiwang581c81a2021-09-06 19:00:55 -070085 Executor executor,
Jakob Buchgraber20342c72019-11-12 04:56:16 -080086 CommandEnvironment env,
chiwang581c81a2021-09-06 19:00:55 -070087 RemoteCache remoteCache,
Jakob Buchgraber20342c72019-11-12 04:56:16 -080088 ListeningScheduledExecutorService retryScheduler,
89 DigestUtil digestUtil) {
Jakob Buchgraber716e4e32019-01-21 07:59:23 -080090 return new RemoteActionContextProvider(
chiwang581c81a2021-09-06 19:00:55 -070091 executor,
92 env,
93 remoteCache,
94 /*remoteExecutor=*/ null,
95 retryScheduler,
96 digestUtil,
97 /*logDir=*/ null);
Jakob Buchgraber716e4e32019-01-21 07:59:23 -080098 }
99
100 public static RemoteActionContextProvider createForRemoteExecution(
chiwang581c81a2021-09-06 19:00:55 -0700101 Executor executor,
Jakob Buchgraber716e4e32019-01-21 07:59:23 -0800102 CommandEnvironment env,
chiwang581c81a2021-09-06 19:00:55 -0700103 RemoteExecutionCache remoteCache,
104 RemoteExecutionClient remoteExecutor,
Jakob Buchgraber20342c72019-11-12 04:56:16 -0800105 ListeningScheduledExecutorService retryScheduler,
Jakob Buchgraber716e4e32019-01-21 07:59:23 -0800106 DigestUtil digestUtil,
107 Path logDir) {
Jakob Buchgraber20342c72019-11-12 04:56:16 -0800108 return new RemoteActionContextProvider(
chiwang581c81a2021-09-06 19:00:55 -0700109 executor, env, remoteCache, remoteExecutor, retryScheduler, digestUtil, logDir);
Jakob Buchgraber716e4e32019-01-21 07:59:23 -0800110 }
111
jhorvitzcd477f22021-05-05 10:18:22 -0700112 private RemotePathResolver createRemotePathResolver() {
Chi Wangb863dbf2021-04-19 00:55:59 -0700113 Path execRoot = env.getExecRoot();
114 BuildLanguageOptions buildLanguageOptions =
115 env.getOptions().getOptions(BuildLanguageOptions.class);
116 RemotePathResolver remotePathResolver;
117 if (buildLanguageOptions != null && buildLanguageOptions.experimentalSiblingRepositoryLayout) {
118 RemoteOptions remoteOptions = checkNotNull(env.getOptions().getOptions(RemoteOptions.class));
119 remotePathResolver =
120 new SiblingRepositoryLayoutResolver(
121 execRoot, remoteOptions.incompatibleRemoteOutputPathsRelativeToInputRoot);
122 } else {
123 remotePathResolver = new DefaultRemotePathResolver(execRoot);
124 }
125 return remotePathResolver;
126 }
127
jhorvitzcd477f22021-05-05 10:18:22 -0700128 private RemoteExecutionService getRemoteExecutionService() {
chiwangae539912021-04-23 00:25:02 -0700129 if (remoteExecutionService == null) {
Chi Wangc785f022021-08-01 22:33:22 -0700130 Path workingDirectory = env.getWorkingDirectory();
131 RemoteOptions remoteOptions = checkNotNull(env.getOptions().getOptions(RemoteOptions.class));
132 Path captureCorruptedOutputsDir = null;
133 if (remoteOptions.remoteCaptureCorruptedOutputs != null
134 && !remoteOptions.remoteCaptureCorruptedOutputs.isEmpty()) {
135 captureCorruptedOutputsDir =
136 workingDirectory.getRelative(remoteOptions.remoteCaptureCorruptedOutputs);
137 }
138
chiwang7f08b782021-09-05 21:04:35 -0700139 boolean verboseFailures =
140 checkNotNull(env.getOptions().getOptions(ExecutionOptions.class)).verboseFailures;
chiwangae539912021-04-23 00:25:02 -0700141 remoteExecutionService =
142 new RemoteExecutionService(
chiwang581c81a2021-09-06 19:00:55 -0700143 executor,
chiwang7f08b782021-09-05 21:04:35 -0700144 env.getReporter(),
145 verboseFailures,
chiwangae539912021-04-23 00:25:02 -0700146 env.getExecRoot(),
147 createRemotePathResolver(),
148 env.getBuildRequestId(),
149 env.getCommandId().toString(),
150 digestUtil,
151 checkNotNull(env.getOptions().getOptions(RemoteOptions.class)),
chiwang581c81a2021-09-06 19:00:55 -0700152 remoteCache,
153 remoteExecutor,
Chi Wangc785f022021-08-01 22:33:22 -0700154 filesToDownload,
155 captureCorruptedOutputsDir);
chiwang7f08b782021-09-05 21:04:35 -0700156 env.getEventBus().register(remoteExecutionService);
chiwangae539912021-04-23 00:25:02 -0700157 }
158
159 return remoteExecutionService;
160 }
161
jcater1d09f572020-03-31 04:44:27 -0700162 /**
163 * Registers a remote spawn strategy if this instance was created with an executor, otherwise does
164 * nothing.
165 *
166 * @param registryBuilder builder with which to register the strategy
167 */
Chi Wang7643d3a2021-06-09 00:29:55 -0700168 public void registerRemoteSpawnStrategy(SpawnStrategyRegistry.Builder registryBuilder) {
janakr619dcf82020-09-22 14:08:59 -0700169 boolean verboseFailures =
170 checkNotNull(env.getOptions().getOptions(ExecutionOptions.class)).verboseFailures;
jcater1d09f572020-03-31 04:44:27 -0700171 RemoteSpawnRunner spawnRunner =
172 new RemoteSpawnRunner(
173 env.getExecRoot(),
174 checkNotNull(env.getOptions().getOptions(RemoteOptions.class)),
175 env.getOptions().getOptions(ExecutionOptions.class),
janakr619dcf82020-09-22 14:08:59 -0700176 verboseFailures,
jcater1d09f572020-03-31 04:44:27 -0700177 env.getReporter(),
jcater1d09f572020-03-31 04:44:27 -0700178 retryScheduler,
jcater1d09f572020-03-31 04:44:27 -0700179 logDir,
chiwangae539912021-04-23 00:25:02 -0700180 getRemoteExecutionService());
jcater1d09f572020-03-31 04:44:27 -0700181 registryBuilder.registerStrategy(
janakr619dcf82020-09-22 14:08:59 -0700182 new RemoteSpawnStrategy(env.getExecRoot(), spawnRunner, verboseFailures), "remote");
jcater1d09f572020-03-31 04:44:27 -0700183 }
184
185 /**
Josh Smith33d0a1c2020-05-05 07:42:37 -0700186 * Registers a spawn cache action context
jcater1d09f572020-03-31 04:44:27 -0700187 *
188 * @param registryBuilder builder with which to register the cache
189 */
Josh Smith33d0a1c2020-05-05 07:42:37 -0700190 public void registerSpawnCache(ModuleActionContextRegistry.Builder registryBuilder) {
jcater1d09f572020-03-31 04:44:27 -0700191 RemoteSpawnCache spawnCache =
192 new RemoteSpawnCache(
193 env.getExecRoot(),
194 checkNotNull(env.getOptions().getOptions(RemoteOptions.class)),
George Gensure54b062c2020-09-02 05:06:40 -0700195 checkNotNull(env.getOptions().getOptions(ExecutionOptions.class)).verboseFailures,
chiwangae539912021-04-23 00:25:02 -0700196 getRemoteExecutionService());
jcater1d09f572020-03-31 04:44:27 -0700197 registryBuilder.register(SpawnCache.class, spawnCache, "remote-cache");
ulfjack3fbd7c42017-07-10 13:19:19 +0200198 }
199
schmitt8b20d1d2020-01-13 10:31:54 -0800200 /** Returns the remote cache. */
Jakob Buchgraber60566092019-11-11 06:28:22 -0800201 RemoteCache getRemoteCache() {
chiwang581c81a2021-09-06 19:00:55 -0700202 return remoteCache;
buchgrd480c5f2019-04-03 00:53:34 -0700203 }
204
Chi Wang7643d3a2021-06-09 00:29:55 -0700205 RemoteExecutionClient getRemoteExecutionClient() {
chiwang581c81a2021-09-06 19:00:55 -0700206 return remoteExecutor;
Chi Wang7643d3a2021-06-09 00:29:55 -0700207 }
208
Jakob Buchgraber11a98a52019-09-02 07:57:02 -0700209 void setFilesToDownload(ImmutableSet<ActionInput> topLevelOutputs) {
210 this.filesToDownload = Preconditions.checkNotNull(topLevelOutputs, "filesToDownload");
Jakob Buchgraber50c10042019-04-11 02:11:19 -0700211 }
212
chiwang7f08b782021-09-05 21:04:35 -0700213 public void afterCommand() {
214 if (remoteExecutionService != null) {
Chi Wang621649d2022-01-26 02:14:29 -0800215 BlockWaitingModule blockWaitingModule =
216 checkNotNull(env.getRuntime().getBlazeModule(BlockWaitingModule.class));
217 blockWaitingModule.submit(() -> remoteExecutionService.shutdown());
chiwang7f08b782021-09-05 21:04:35 -0700218 } else {
chiwang581c81a2021-09-06 19:00:55 -0700219 if (remoteCache != null) {
220 remoteCache.release();
chiwang7f08b782021-09-05 21:04:35 -0700221 }
chiwang581c81a2021-09-06 19:00:55 -0700222 if (remoteExecutor != null) {
223 remoteExecutor.close();
chiwang7f08b782021-09-05 21:04:35 -0700224 }
buchgrb50fe862018-07-12 04:01:45 -0700225 }
Alpha Lam79adf592016-02-10 15:38:59 +0000226 }
227}