Skip to content

Commit 4cfd32d

Browse files
Bencodescopybara-github
authored andcommitted
Support multiplex workers in ResourceProcessorBusyBox
Adding support for multiplex workers inside of `ResourceProcessorBusyBox` and moving it's worker implementation over to the generic work request handler. These PRs need to land for this to work: - #14424 - #14425 - #14427 For those not on rolling releases, the other required PRs that have already merged are: - #14144 - #14145 - #14146 Closes #14428. PiperOrigin-RevId: 456561596 Change-Id: I098d5a323ac6558ad0f5f8190e29f45a7a37b4d4
1 parent 523209c commit 4cfd32d

File tree

7 files changed

+94
-34
lines changed

7 files changed

+94
-34
lines changed

src/main/java/com/google/devtools/build/lib/actions/ExecutionRequirements.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ public enum WorkerProtocolFormat {
176176
public static final ImmutableMap<String, String> WORKER_MODE_ENABLED =
177177
ImmutableMap.of(SUPPORTS_WORKERS, "1");
178178

179+
public static final ImmutableMap<String, String> WORKER_MULTIPLEX_MODE_ENABLED =
180+
ImmutableMap.of(SUPPORTS_MULTIPLEX_WORKERS, "1");
181+
179182
/**
180183
* Requires local execution without sandboxing for a spawn.
181184
*

src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,17 @@ public static class Options extends FragmentOptions {
882882
help = "Tracking flag for when busybox workers are enabled.")
883883
public boolean persistentBusyboxTools;
884884

885+
@Option(
886+
name = "experimental_persistent_multiplex_busybox_tools",
887+
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
888+
effectTags = {
889+
OptionEffectTag.HOST_MACHINE_RESOURCE_OPTIMIZATIONS,
890+
OptionEffectTag.EXECUTION,
891+
},
892+
defaultValue = "false",
893+
help = "Tracking flag for when multiplex busybox workers are enabled.")
894+
public boolean experimentalPersistentMultiplexBusyboxTools;
895+
885896
@Option(
886897
name = "experimental_remove_r_classes_from_instrumentation_test_jar",
887898
defaultValue = "true",
@@ -1007,6 +1018,8 @@ public FragmentOptions getHost() {
10071018
host.oneVersionEnforcementUseTransitiveJarsForBinaryUnderTest =
10081019
oneVersionEnforcementUseTransitiveJarsForBinaryUnderTest;
10091020
host.persistentBusyboxTools = persistentBusyboxTools;
1021+
host.experimentalPersistentMultiplexBusyboxTools =
1022+
experimentalPersistentMultiplexBusyboxTools;
10101023

10111024
// Unless the build was started from an Android device, host means MAIN.
10121025
host.configurationDistinguisher = ConfigurationDistinguisher.MAIN;
@@ -1052,6 +1065,7 @@ public FragmentOptions getHost() {
10521065
private final boolean dataBindingUpdatedArgs;
10531066
private final boolean dataBindingAndroidX;
10541067
private final boolean persistentBusyboxTools;
1068+
private final boolean experimentalPersistentMultiplexBusyboxTools;
10551069
private final boolean filterRJarsFromAndroidTest;
10561070
private final boolean removeRClassesFromInstrumentationTestJar;
10571071
private final boolean alwaysFilterDuplicateClassesFromAndroidTest;
@@ -1111,6 +1125,8 @@ public AndroidConfiguration(BuildOptions buildOptions) throws InvalidConfigurati
11111125
this.dataBindingUpdatedArgs = options.dataBindingUpdatedArgs;
11121126
this.dataBindingAndroidX = options.dataBindingAndroidX;
11131127
this.persistentBusyboxTools = options.persistentBusyboxTools;
1128+
this.experimentalPersistentMultiplexBusyboxTools =
1129+
options.experimentalPersistentMultiplexBusyboxTools;
11141130
this.filterRJarsFromAndroidTest = options.filterRJarsFromAndroidTest;
11151131
this.removeRClassesFromInstrumentationTestJar =
11161132
options.removeRClassesFromInstrumentationTestJar;
@@ -1362,6 +1378,11 @@ public boolean persistentBusyboxTools() {
13621378
return persistentBusyboxTools;
13631379
}
13641380

1381+
@Override
1382+
public boolean persistentMultiplexBusyboxTools() {
1383+
return experimentalPersistentMultiplexBusyboxTools;
1384+
}
1385+
13651386
@Override
13661387
public boolean incompatibleUseToolchainResolution() {
13671388
return incompatibleUseToolchainResolution;

src/main/java/com/google/devtools/build/lib/rules/android/AndroidDataContext.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public class AndroidDataContext implements AndroidDataContextApi {
6464
private final FilesToRunProvider busybox;
6565
private final AndroidSdkProvider sdk;
6666
private final boolean persistentBusyboxToolsEnabled;
67+
private final boolean persistentMultiplexBusyboxTools;
6768
private final boolean optOutOfResourcePathShortening;
6869
private final boolean optOutOfResourceNameObfuscation;
6970
private final boolean throwOnShrinkResources;
@@ -90,6 +91,7 @@ public static AndroidDataContext makeContext(RuleContext ruleContext) {
9091
ruleContext,
9192
ruleContext.getExecutablePrerequisite("$android_resources_busybox"),
9293
androidConfig.persistentBusyboxTools(),
94+
androidConfig.persistentMultiplexBusyboxTools(),
9395
AndroidSdkProvider.fromRuleContext(ruleContext),
9496
hasExemption(ruleContext, "allow_raw_access_to_resource_paths", false),
9597
hasExemption(ruleContext, "allow_resource_name_obfuscation_opt_out", false),
@@ -114,6 +116,7 @@ protected AndroidDataContext(
114116
RuleContext ruleContext,
115117
FilesToRunProvider busybox,
116118
boolean persistentBusyboxToolsEnabled,
119+
boolean persistentMultiplexBusyboxTools,
117120
AndroidSdkProvider sdk,
118121
boolean optOutOfResourcePathShortening,
119122
boolean optOutOfResourceNameObfuscation,
@@ -126,6 +129,7 @@ protected AndroidDataContext(
126129
boolean includeProguardLocationReferences,
127130
ImmutableMap<String, String> executionInfo) {
128131
this.persistentBusyboxToolsEnabled = persistentBusyboxToolsEnabled;
132+
this.persistentMultiplexBusyboxTools = persistentMultiplexBusyboxTools;
129133
this.ruleContext = ruleContext;
130134
this.busybox = busybox;
131135
this.sdk = sdk;
@@ -222,6 +226,10 @@ public boolean isPersistentBusyboxToolsEnabled() {
222226
return persistentBusyboxToolsEnabled;
223227
}
224228

229+
public boolean isPersistentMultiplexBusyboxTools() {
230+
return persistentMultiplexBusyboxTools;
231+
}
232+
225233
public boolean optOutOfResourcePathShortening() {
226234
return optOutOfResourcePathShortening;
227235
}

src/main/java/com/google/devtools/build/lib/rules/android/BusyBoxActionBuilder.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,10 +344,12 @@ public void buildAndRegister(String message, String mnemonic) {
344344

345345
if (dataContext.isPersistentBusyboxToolsEnabled()) {
346346
commandLine.add("--logWarnings=false");
347-
spawnActionBuilder
348-
.addCommandLine(commandLine.build(), WORKERS_FORCED_PARAM_FILE_INFO);
349-
347+
spawnActionBuilder.addCommandLine(commandLine.build(), WORKERS_FORCED_PARAM_FILE_INFO);
350348
executionInfo.putAll(ExecutionRequirements.WORKER_MODE_ENABLED);
349+
350+
if (dataContext.isPersistentMultiplexBusyboxTools()) {
351+
executionInfo.putAll(ExecutionRequirements.WORKER_MULTIPLEX_MODE_ENABLED);
352+
}
351353
} else {
352354
spawnActionBuilder.addCommandLine(commandLine.build(), FORCED_PARAM_FILE_INFO);
353355
}

src/main/java/com/google/devtools/build/lib/starlarkbuildapi/android/AndroidConfigurationApi.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,13 @@ public interface AndroidConfigurationApi extends StarlarkValue {
231231
documented = false)
232232
boolean persistentBusyboxTools();
233233

234+
@StarlarkMethod(
235+
name = "experimental_persistent_multiplex_busybox_tools",
236+
structField = true,
237+
doc = "",
238+
documented = false)
239+
boolean persistentMultiplexBusyboxTools();
240+
234241
@StarlarkMethod(
235242
name = "get_output_directory_name",
236243
structField = true,

src/tools/android/java/com/google/devtools/build/android/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ java_library(
7676
":dependency_info",
7777
"//src/java_tools/singlejar/java/com/google/devtools/build/singlejar:libSingleJar",
7878
"//src/java_tools/singlejar/java/com/google/devtools/build/zip",
79+
"//src/main/java/com/google/devtools/build/lib/worker",
80+
"//src/main/java/com/google/devtools/build/lib/worker:work_request_handlers",
7981
"//src/main/java/com/google/devtools/common/options",
8082
"//src/main/protobuf:worker_protocol_java_proto",
8183
"//src/tools/android/java/com/google/devtools/build/android/junctions",

src/tools/android/java/com/google/devtools/build/android/ResourceProcessorBusyBox.java

Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414

1515
package com.google.devtools.build.android;
1616

17+
import static java.nio.charset.StandardCharsets.UTF_8;
18+
1719
import com.google.devtools.build.android.aapt2.Aapt2Exception;
1820
import com.google.devtools.build.android.resources.JavaIdentifierValidator.InvalidJavaIdentifier;
19-
import com.google.devtools.build.lib.worker.WorkerProtocol.WorkRequest;
20-
import com.google.devtools.build.lib.worker.WorkerProtocol.WorkResponse;
21+
import com.google.devtools.build.lib.worker.ProtoWorkerMessageProcessor;
22+
import com.google.devtools.build.lib.worker.WorkRequestHandler;
2123
import com.google.devtools.common.options.EnumConverter;
2224
import com.google.devtools.common.options.Option;
2325
import com.google.devtools.common.options.OptionDocumentationCategory;
@@ -30,7 +32,9 @@
3032
import java.io.IOException;
3133
import java.io.InputStream;
3234
import java.io.PrintStream;
35+
import java.io.PrintWriter;
3336
import java.nio.file.FileSystems;
37+
import java.time.Duration;
3438
import java.util.Arrays;
3539
import java.util.List;
3640
import java.util.Properties;
@@ -183,43 +187,56 @@ private static int runPersistentWorker() throws Exception {
183187
PrintStream ps = new PrintStream(buf, true);
184188
PrintStream realStdOut = System.out;
185189
PrintStream realStdErr = System.err;
186-
try {
187-
// Redirect all stdout and stderr output for logging.
188-
System.setOut(ps);
189-
System.setErr(ps);
190-
191-
while (true) {
192-
try {
193-
WorkRequest request = WorkRequest.parseDelimitedFrom(System.in);
194-
if (request == null) {
195-
break;
196-
}
197-
198-
int exitCode = processRequest(request.getArgumentsList());
199-
ps.flush();
200-
201-
WorkResponse.newBuilder()
202-
.setExitCode(exitCode)
203-
.setRequestId(request.getRequestId())
204-
.setOutput(buf.toString())
205-
.build()
206-
.writeDelimitedTo(realStdOut);
207190

208-
realStdOut.flush();
209-
buf.reset();
210-
} catch (IOException e) {
211-
logger.severe(e.getMessage());
212-
e.printStackTrace(realStdErr);
213-
return 1;
214-
}
215-
}
191+
// Redirect all stdout and stderr output for logging.
192+
System.setOut(ps);
193+
System.setErr(ps);
194+
try {
195+
WorkRequestHandler workerHandler =
196+
new WorkRequestHandler.WorkRequestHandlerBuilder(
197+
new WorkRequestHandler.WorkRequestCallback(
198+
(request, pw) -> processRequest(request.getArgumentsList(), pw, buf)),
199+
realStdErr,
200+
new ProtoWorkerMessageProcessor(System.in, realStdOut))
201+
.setCpuUsageBeforeGc(Duration.ofSeconds(10))
202+
.build();
203+
workerHandler.processRequests();
204+
} catch (IOException e) {
205+
logger.severe(e.getMessage());
206+
e.printStackTrace(realStdErr);
207+
return 1;
216208
} finally {
217209
System.setOut(realStdOut);
218210
System.setErr(realStdErr);
219211
}
220212
return 0;
221213
}
222214

215+
/**
216+
* Processes the request for the given args and writes the captured byte array buffer to the
217+
* WorkRequestHandler print writer.
218+
*/
219+
private static int processRequest(List<String> args, PrintWriter pw, ByteArrayOutputStream buf) {
220+
int exitCode;
221+
try {
222+
// Process the actual request and grab the exit code
223+
exitCode = processRequest(args);
224+
} catch (Exception e) {
225+
e.printStackTrace(pw);
226+
exitCode = 1;
227+
} finally {
228+
// Write the captured buffer to the work response. We synchronize to avoid race conditions
229+
// while reading from and calling reset on the shared ByteArrayOutputStream.
230+
synchronized (buf) {
231+
String captured = buf.toString(UTF_8).trim();
232+
buf.reset();
233+
pw.print(captured);
234+
}
235+
}
236+
237+
return exitCode;
238+
}
239+
223240
private static int processRequest(List<String> args) throws Exception {
224241
OptionsParser optionsParser =
225242
OptionsParser.builder()

0 commit comments

Comments
 (0)