Alpha Lam | 79adf59 | 2016-02-10 15:38:59 +0000 | [diff] [blame] | 1 | // 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 Lam | 79adf59 | 2016-02-10 15:38:59 +0000 | [diff] [blame] | 14 | package com.google.devtools.build.lib.remote; |
| 15 | |
buchgr | bcbd2da | 2017-07-14 14:58:07 +0200 | [diff] [blame] | 16 | import static com.google.common.base.Preconditions.checkNotNull; |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 17 | import static com.google.common.util.concurrent.MoreExecutors.directExecutor; |
buchgr | bcbd2da | 2017-07-14 14:58:07 +0200 | [diff] [blame] | 18 | |
philwo | d6ce264 | 2018-07-30 05:24:50 -0700 | [diff] [blame] | 19 | import com.google.common.base.Preconditions; |
Jakob Buchgraber | 50c1004 | 2019-04-11 02:11:19 -0700 | [diff] [blame] | 20 | import com.google.common.collect.ImmutableSet; |
Jakob Buchgraber | 20342c7 | 2019-11-12 04:56:16 -0800 | [diff] [blame] | 21 | import com.google.common.util.concurrent.ListeningScheduledExecutorService; |
Jakob Buchgraber | 34784c3 | 2019-07-22 07:40:14 -0700 | [diff] [blame] | 22 | import com.google.devtools.build.lib.actions.ActionInput; |
Alpha Lam | 79adf59 | 2016-02-10 15:38:59 +0000 | [diff] [blame] | 23 | import com.google.devtools.build.lib.exec.ExecutionOptions; |
jcater | 1d09f57 | 2020-03-31 04:44:27 -0700 | [diff] [blame] | 24 | import com.google.devtools.build.lib.exec.ModuleActionContextRegistry; |
schmitt | f8f59bc | 2020-01-15 10:05:18 -0800 | [diff] [blame] | 25 | import com.google.devtools.build.lib.exec.SpawnCache; |
jcater | 1d09f57 | 2020-03-31 04:44:27 -0700 | [diff] [blame] | 26 | import com.google.devtools.build.lib.exec.SpawnStrategyRegistry; |
Chi Wang | b863dbf | 2021-04-19 00:55:59 -0700 | [diff] [blame] | 27 | import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions; |
Chi Wang | 09d8f14 | 2020-10-30 01:03:16 -0700 | [diff] [blame] | 28 | import com.google.devtools.build.lib.remote.common.RemoteExecutionClient; |
Chi Wang | b863dbf | 2021-04-19 00:55:59 -0700 | [diff] [blame] | 29 | import com.google.devtools.build.lib.remote.common.RemotePathResolver; |
| 30 | import com.google.devtools.build.lib.remote.common.RemotePathResolver.DefaultRemotePathResolver; |
| 31 | import com.google.devtools.build.lib.remote.common.RemotePathResolver.SiblingRepositoryLayoutResolver; |
Jakob Buchgraber | 75b7ed4 | 2019-03-27 10:27:13 -0700 | [diff] [blame] | 32 | import com.google.devtools.build.lib.remote.options.RemoteOptions; |
Googler | 922d1e6 | 2018-03-05 14:49:00 -0800 | [diff] [blame] | 33 | import com.google.devtools.build.lib.remote.util.DigestUtil; |
Chi Wang | 621649d | 2022-01-26 02:14:29 -0800 | [diff] [blame^] | 34 | import com.google.devtools.build.lib.runtime.BlockWaitingModule; |
Alpha Lam | 79adf59 | 2016-02-10 15:38:59 +0000 | [diff] [blame] | 35 | import com.google.devtools.build.lib.runtime.CommandEnvironment; |
olaola | bf326fa | 2018-03-21 11:22:12 -0700 | [diff] [blame] | 36 | import com.google.devtools.build.lib.vfs.Path; |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 37 | import java.util.concurrent.Executor; |
buchgr | bcbd2da | 2017-07-14 14:58:07 +0200 | [diff] [blame] | 38 | import javax.annotation.Nullable; |
Alpha Lam | 79adf59 | 2016-02-10 15:38:59 +0000 | [diff] [blame] | 39 | |
jhorvitz | cd477f2 | 2021-05-05 10:18:22 -0700 | [diff] [blame] | 40 | /** Provides a remote execution context. */ |
chiwang | 7f08b78 | 2021-09-05 21:04:35 -0700 | [diff] [blame] | 41 | final class RemoteActionContextProvider { |
schmitt | 1bbb1e1 | 2020-01-17 08:14:14 -0800 | [diff] [blame] | 42 | |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 43 | private final Executor executor; |
ulfjack | acd291a | 2017-06-16 15:25:42 +0200 | [diff] [blame] | 44 | private final CommandEnvironment env; |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 45 | @Nullable private final RemoteCache remoteCache; |
| 46 | @Nullable private final RemoteExecutionClient remoteExecutor; |
Jakob Buchgraber | 6bcdf11 | 2019-11-13 06:53:55 -0800 | [diff] [blame] | 47 | @Nullable private final ListeningScheduledExecutorService retryScheduler; |
buchgr | 559a07d | 2017-11-30 11:09:35 -0800 | [diff] [blame] | 48 | private final DigestUtil digestUtil; |
Jakob Buchgraber | 716e4e3 | 2019-01-21 07:59:23 -0800 | [diff] [blame] | 49 | @Nullable private final Path logDir; |
Jakob Buchgraber | 11a98a5 | 2019-09-02 07:57:02 -0700 | [diff] [blame] | 50 | private ImmutableSet<ActionInput> filesToDownload = ImmutableSet.of(); |
chiwang | ae53991 | 2021-04-23 00:25:02 -0700 | [diff] [blame] | 51 | private RemoteExecutionService remoteExecutionService; |
buchgr | bcbd2da | 2017-07-14 14:58:07 +0200 | [diff] [blame] | 52 | |
Jakob Buchgraber | 716e4e3 | 2019-01-21 07:59:23 -0800 | [diff] [blame] | 53 | private RemoteActionContextProvider( |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 54 | Executor executor, |
buchgr | 559a07d | 2017-11-30 11:09:35 -0800 | [diff] [blame] | 55 | CommandEnvironment env, |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 56 | @Nullable RemoteCache remoteCache, |
| 57 | @Nullable RemoteExecutionClient remoteExecutor, |
Jakob Buchgraber | 20342c7 | 2019-11-12 04:56:16 -0800 | [diff] [blame] | 58 | @Nullable ListeningScheduledExecutorService retryScheduler, |
olaola | bf326fa | 2018-03-21 11:22:12 -0700 | [diff] [blame] | 59 | DigestUtil digestUtil, |
Jakob Buchgraber | 716e4e3 | 2019-01-21 07:59:23 -0800 | [diff] [blame] | 60 | @Nullable Path logDir) { |
buchgr | bcbd2da | 2017-07-14 14:58:07 +0200 | [diff] [blame] | 61 | this.executor = executor; |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 62 | this.env = Preconditions.checkNotNull(env, "env"); |
| 63 | this.remoteCache = remoteCache; |
| 64 | this.remoteExecutor = remoteExecutor; |
Jakob Buchgraber | 20342c7 | 2019-11-12 04:56:16 -0800 | [diff] [blame] | 65 | this.retryScheduler = retryScheduler; |
buchgr | 559a07d | 2017-11-30 11:09:35 -0800 | [diff] [blame] | 66 | this.digestUtil = digestUtil; |
olaola | bf326fa | 2018-03-21 11:22:12 -0700 | [diff] [blame] | 67 | this.logDir = logDir; |
Alpha Lam | 79adf59 | 2016-02-10 15:38:59 +0000 | [diff] [blame] | 68 | } |
| 69 | |
Chi Wang | 7643d3a | 2021-06-09 00:29:55 -0700 | [diff] [blame] | 70 | public static RemoteActionContextProvider createForPlaceholder( |
| 71 | CommandEnvironment env, |
| 72 | ListeningScheduledExecutorService retryScheduler, |
| 73 | DigestUtil digestUtil) { |
| 74 | return new RemoteActionContextProvider( |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 75 | directExecutor(), |
| 76 | env, |
| 77 | /*remoteCache=*/ null, |
| 78 | /*remoteExecutor=*/ null, |
| 79 | retryScheduler, |
| 80 | digestUtil, |
| 81 | /*logDir=*/ null); |
Chi Wang | 7643d3a | 2021-06-09 00:29:55 -0700 | [diff] [blame] | 82 | } |
| 83 | |
Jakob Buchgraber | 716e4e3 | 2019-01-21 07:59:23 -0800 | [diff] [blame] | 84 | public static RemoteActionContextProvider createForRemoteCaching( |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 85 | Executor executor, |
Jakob Buchgraber | 20342c7 | 2019-11-12 04:56:16 -0800 | [diff] [blame] | 86 | CommandEnvironment env, |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 87 | RemoteCache remoteCache, |
Jakob Buchgraber | 20342c7 | 2019-11-12 04:56:16 -0800 | [diff] [blame] | 88 | ListeningScheduledExecutorService retryScheduler, |
| 89 | DigestUtil digestUtil) { |
Jakob Buchgraber | 716e4e3 | 2019-01-21 07:59:23 -0800 | [diff] [blame] | 90 | return new RemoteActionContextProvider( |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 91 | executor, |
| 92 | env, |
| 93 | remoteCache, |
| 94 | /*remoteExecutor=*/ null, |
| 95 | retryScheduler, |
| 96 | digestUtil, |
| 97 | /*logDir=*/ null); |
Jakob Buchgraber | 716e4e3 | 2019-01-21 07:59:23 -0800 | [diff] [blame] | 98 | } |
| 99 | |
| 100 | public static RemoteActionContextProvider createForRemoteExecution( |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 101 | Executor executor, |
Jakob Buchgraber | 716e4e3 | 2019-01-21 07:59:23 -0800 | [diff] [blame] | 102 | CommandEnvironment env, |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 103 | RemoteExecutionCache remoteCache, |
| 104 | RemoteExecutionClient remoteExecutor, |
Jakob Buchgraber | 20342c7 | 2019-11-12 04:56:16 -0800 | [diff] [blame] | 105 | ListeningScheduledExecutorService retryScheduler, |
Jakob Buchgraber | 716e4e3 | 2019-01-21 07:59:23 -0800 | [diff] [blame] | 106 | DigestUtil digestUtil, |
| 107 | Path logDir) { |
Jakob Buchgraber | 20342c7 | 2019-11-12 04:56:16 -0800 | [diff] [blame] | 108 | return new RemoteActionContextProvider( |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 109 | executor, env, remoteCache, remoteExecutor, retryScheduler, digestUtil, logDir); |
Jakob Buchgraber | 716e4e3 | 2019-01-21 07:59:23 -0800 | [diff] [blame] | 110 | } |
| 111 | |
jhorvitz | cd477f2 | 2021-05-05 10:18:22 -0700 | [diff] [blame] | 112 | private RemotePathResolver createRemotePathResolver() { |
Chi Wang | b863dbf | 2021-04-19 00:55:59 -0700 | [diff] [blame] | 113 | 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 | |
jhorvitz | cd477f2 | 2021-05-05 10:18:22 -0700 | [diff] [blame] | 128 | private RemoteExecutionService getRemoteExecutionService() { |
chiwang | ae53991 | 2021-04-23 00:25:02 -0700 | [diff] [blame] | 129 | if (remoteExecutionService == null) { |
Chi Wang | c785f02 | 2021-08-01 22:33:22 -0700 | [diff] [blame] | 130 | 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 | |
chiwang | 7f08b78 | 2021-09-05 21:04:35 -0700 | [diff] [blame] | 139 | boolean verboseFailures = |
| 140 | checkNotNull(env.getOptions().getOptions(ExecutionOptions.class)).verboseFailures; |
chiwang | ae53991 | 2021-04-23 00:25:02 -0700 | [diff] [blame] | 141 | remoteExecutionService = |
| 142 | new RemoteExecutionService( |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 143 | executor, |
chiwang | 7f08b78 | 2021-09-05 21:04:35 -0700 | [diff] [blame] | 144 | env.getReporter(), |
| 145 | verboseFailures, |
chiwang | ae53991 | 2021-04-23 00:25:02 -0700 | [diff] [blame] | 146 | env.getExecRoot(), |
| 147 | createRemotePathResolver(), |
| 148 | env.getBuildRequestId(), |
| 149 | env.getCommandId().toString(), |
| 150 | digestUtil, |
| 151 | checkNotNull(env.getOptions().getOptions(RemoteOptions.class)), |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 152 | remoteCache, |
| 153 | remoteExecutor, |
Chi Wang | c785f02 | 2021-08-01 22:33:22 -0700 | [diff] [blame] | 154 | filesToDownload, |
| 155 | captureCorruptedOutputsDir); |
chiwang | 7f08b78 | 2021-09-05 21:04:35 -0700 | [diff] [blame] | 156 | env.getEventBus().register(remoteExecutionService); |
chiwang | ae53991 | 2021-04-23 00:25:02 -0700 | [diff] [blame] | 157 | } |
| 158 | |
| 159 | return remoteExecutionService; |
| 160 | } |
| 161 | |
jcater | 1d09f57 | 2020-03-31 04:44:27 -0700 | [diff] [blame] | 162 | /** |
| 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 Wang | 7643d3a | 2021-06-09 00:29:55 -0700 | [diff] [blame] | 168 | public void registerRemoteSpawnStrategy(SpawnStrategyRegistry.Builder registryBuilder) { |
janakr | 619dcf8 | 2020-09-22 14:08:59 -0700 | [diff] [blame] | 169 | boolean verboseFailures = |
| 170 | checkNotNull(env.getOptions().getOptions(ExecutionOptions.class)).verboseFailures; |
jcater | 1d09f57 | 2020-03-31 04:44:27 -0700 | [diff] [blame] | 171 | RemoteSpawnRunner spawnRunner = |
| 172 | new RemoteSpawnRunner( |
| 173 | env.getExecRoot(), |
| 174 | checkNotNull(env.getOptions().getOptions(RemoteOptions.class)), |
| 175 | env.getOptions().getOptions(ExecutionOptions.class), |
janakr | 619dcf8 | 2020-09-22 14:08:59 -0700 | [diff] [blame] | 176 | verboseFailures, |
jcater | 1d09f57 | 2020-03-31 04:44:27 -0700 | [diff] [blame] | 177 | env.getReporter(), |
jcater | 1d09f57 | 2020-03-31 04:44:27 -0700 | [diff] [blame] | 178 | retryScheduler, |
jcater | 1d09f57 | 2020-03-31 04:44:27 -0700 | [diff] [blame] | 179 | logDir, |
chiwang | ae53991 | 2021-04-23 00:25:02 -0700 | [diff] [blame] | 180 | getRemoteExecutionService()); |
jcater | 1d09f57 | 2020-03-31 04:44:27 -0700 | [diff] [blame] | 181 | registryBuilder.registerStrategy( |
janakr | 619dcf8 | 2020-09-22 14:08:59 -0700 | [diff] [blame] | 182 | new RemoteSpawnStrategy(env.getExecRoot(), spawnRunner, verboseFailures), "remote"); |
jcater | 1d09f57 | 2020-03-31 04:44:27 -0700 | [diff] [blame] | 183 | } |
| 184 | |
| 185 | /** |
Josh Smith | 33d0a1c | 2020-05-05 07:42:37 -0700 | [diff] [blame] | 186 | * Registers a spawn cache action context |
jcater | 1d09f57 | 2020-03-31 04:44:27 -0700 | [diff] [blame] | 187 | * |
| 188 | * @param registryBuilder builder with which to register the cache |
| 189 | */ |
Josh Smith | 33d0a1c | 2020-05-05 07:42:37 -0700 | [diff] [blame] | 190 | public void registerSpawnCache(ModuleActionContextRegistry.Builder registryBuilder) { |
jcater | 1d09f57 | 2020-03-31 04:44:27 -0700 | [diff] [blame] | 191 | RemoteSpawnCache spawnCache = |
| 192 | new RemoteSpawnCache( |
| 193 | env.getExecRoot(), |
| 194 | checkNotNull(env.getOptions().getOptions(RemoteOptions.class)), |
George Gensure | 54b062c | 2020-09-02 05:06:40 -0700 | [diff] [blame] | 195 | checkNotNull(env.getOptions().getOptions(ExecutionOptions.class)).verboseFailures, |
chiwang | ae53991 | 2021-04-23 00:25:02 -0700 | [diff] [blame] | 196 | getRemoteExecutionService()); |
jcater | 1d09f57 | 2020-03-31 04:44:27 -0700 | [diff] [blame] | 197 | registryBuilder.register(SpawnCache.class, spawnCache, "remote-cache"); |
ulfjack | 3fbd7c4 | 2017-07-10 13:19:19 +0200 | [diff] [blame] | 198 | } |
| 199 | |
schmitt | 8b20d1d | 2020-01-13 10:31:54 -0800 | [diff] [blame] | 200 | /** Returns the remote cache. */ |
Jakob Buchgraber | 6056609 | 2019-11-11 06:28:22 -0800 | [diff] [blame] | 201 | RemoteCache getRemoteCache() { |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 202 | return remoteCache; |
buchgr | d480c5f | 2019-04-03 00:53:34 -0700 | [diff] [blame] | 203 | } |
| 204 | |
Chi Wang | 7643d3a | 2021-06-09 00:29:55 -0700 | [diff] [blame] | 205 | RemoteExecutionClient getRemoteExecutionClient() { |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 206 | return remoteExecutor; |
Chi Wang | 7643d3a | 2021-06-09 00:29:55 -0700 | [diff] [blame] | 207 | } |
| 208 | |
Jakob Buchgraber | 11a98a5 | 2019-09-02 07:57:02 -0700 | [diff] [blame] | 209 | void setFilesToDownload(ImmutableSet<ActionInput> topLevelOutputs) { |
| 210 | this.filesToDownload = Preconditions.checkNotNull(topLevelOutputs, "filesToDownload"); |
Jakob Buchgraber | 50c1004 | 2019-04-11 02:11:19 -0700 | [diff] [blame] | 211 | } |
| 212 | |
chiwang | 7f08b78 | 2021-09-05 21:04:35 -0700 | [diff] [blame] | 213 | public void afterCommand() { |
| 214 | if (remoteExecutionService != null) { |
Chi Wang | 621649d | 2022-01-26 02:14:29 -0800 | [diff] [blame^] | 215 | BlockWaitingModule blockWaitingModule = |
| 216 | checkNotNull(env.getRuntime().getBlazeModule(BlockWaitingModule.class)); |
| 217 | blockWaitingModule.submit(() -> remoteExecutionService.shutdown()); |
chiwang | 7f08b78 | 2021-09-05 21:04:35 -0700 | [diff] [blame] | 218 | } else { |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 219 | if (remoteCache != null) { |
| 220 | remoteCache.release(); |
chiwang | 7f08b78 | 2021-09-05 21:04:35 -0700 | [diff] [blame] | 221 | } |
chiwang | 581c81a | 2021-09-06 19:00:55 -0700 | [diff] [blame] | 222 | if (remoteExecutor != null) { |
| 223 | remoteExecutor.close(); |
chiwang | 7f08b78 | 2021-09-05 21:04:35 -0700 | [diff] [blame] | 224 | } |
buchgr | b50fe86 | 2018-07-12 04:01:45 -0700 | [diff] [blame] | 225 | } |
Alpha Lam | 79adf59 | 2016-02-10 15:38:59 +0000 | [diff] [blame] | 226 | } |
| 227 | } |