Propagate a persistent worker's worker protocol format from its rule's execution requirements
RELNOTES: None
PiperOrigin-RevId: 325481408
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ExecutionRequirements.java b/src/main/java/com/google/devtools/build/lib/actions/ExecutionRequirements.java
index 4b32bcd..3150e2c 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/ExecutionRequirements.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/ExecutionRequirements.java
@@ -157,6 +157,9 @@
public static final String SUPPORTS_MULTIPLEX_WORKERS = "supports-multiplex-workers";
+ /** Specify the type of worker protocol the worker uses. */
+ public static final String WORKER_PROTOCOL = "worker-protocol";
+
/** Denotes what the type of worker protocol the worker uses. */
public enum WorkerProtocolFormat {
JSON,
diff --git a/src/main/java/com/google/devtools/build/lib/actions/Spawns.java b/src/main/java/com/google/devtools/build/lib/actions/Spawns.java
index d84b8fc..0f4f8c1 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/Spawns.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/Spawns.java
@@ -20,6 +20,7 @@
import com.google.devtools.build.lib.util.CommandDescriptionForm;
import com.google.devtools.build.lib.util.CommandFailureUtils;
import com.google.devtools.build.lib.vfs.Path;
+import java.io.IOException;
import java.time.Duration;
import java.util.Collection;
import java.util.Map;
@@ -91,6 +92,29 @@
.equals(spawn.getExecutionInfo().get(ExecutionRequirements.SUPPORTS_MULTIPLEX_WORKERS));
}
+ /**
+ * Returns which worker protocol format a Spawn claims a persistent worker uses. Defaults to proto
+ * if the protocol format is not specified.
+ */
+ public static ExecutionRequirements.WorkerProtocolFormat getWorkerProtocolFormat(Spawn spawn)
+ throws IOException {
+ String protocolFormat = spawn.getExecutionInfo().get(ExecutionRequirements.WORKER_PROTOCOL);
+
+ if (protocolFormat != null) {
+ switch (protocolFormat) {
+ case "json":
+ return ExecutionRequirements.WorkerProtocolFormat.JSON;
+ case "proto":
+ return ExecutionRequirements.WorkerProtocolFormat.PROTO;
+ default:
+ throw new IOException(
+ "protocol-format must be set to a valid worker protocol format: json or proto");
+ }
+ } else {
+ return ExecutionRequirements.WorkerProtocolFormat.PROTO;
+ }
+ }
+
/** Returns the mnemonic that should be used in the worker's key. */
public static String getWorkerKeyMnemonic(Spawn spawn) {
String customValue = spawn.getExecutionInfo().get(ExecutionRequirements.WORKER_KEY_MNEMONIC);
diff --git a/src/main/java/com/google/devtools/build/lib/worker/WorkerOptions.java b/src/main/java/com/google/devtools/build/lib/worker/WorkerOptions.java
index 7eaf64e..6dd1eb2 100644
--- a/src/main/java/com/google/devtools/build/lib/worker/WorkerOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/worker/WorkerOptions.java
@@ -46,6 +46,16 @@
})
public Void experimentalPersistentJavac;
+ @Option(
+ name = "experimental_allow_json_worker_protocol",
+ defaultValue = "false",
+ documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
+ effectTags = {OptionEffectTag.BUILD_FILE_SEMANTICS},
+ help =
+ "Allows workers to use the JSON worker protocol until it is determined to be"
+ + " stable.")
+ public boolean experimentalJsonWorkerProtocol;
+
/**
* Defines a resource converter for named values in the form [name=]value, where the value is
* {@link ResourceConverter.FLAG_SYNTAX}. If no name is provided (used when setting a default),
diff --git a/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java
index 627dcd2..6f96c69 100644
--- a/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/worker/WorkerSpawnRunner.java
@@ -193,8 +193,14 @@
context.getInputMapping(), spawn, context.getArtifactExpander(), execRoot);
SandboxOutputs outputs = helpers.getOutputs(spawn);
- /** TODO(karlgray): Determine protocolFormat from Spawn. */
- WorkerProtocolFormat protocolFormat = WorkerProtocolFormat.PROTO;
+ WorkerProtocolFormat protocolFormat = Spawns.getWorkerProtocolFormat(spawn);
+ if (!workerOptions.experimentalJsonWorkerProtocol) {
+ if (protocolFormat == WorkerProtocolFormat.JSON) {
+ throw new IOException(
+ "Persistent worker protocol format must be set to proto unless"
+ + " --experimentalJsonWorkerProtocol is used");
+ }
+ }
WorkerKey key =
new WorkerKey(
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/BUILD b/src/test/java/com/google/devtools/build/lib/analysis/BUILD
index c88111a..f9c5131 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/analysis/BUILD
@@ -40,6 +40,7 @@
"//src/main/java/com/google/devtools/build/lib/actions",
"//src/main/java/com/google/devtools/build/lib/actions:action_lookup_key",
"//src/main/java/com/google/devtools/build/lib/actions:artifacts",
+ "//src/main/java/com/google/devtools/build/lib/actions:execution_requirements",
"//src/main/java/com/google/devtools/build/lib/analysis:actions/binary_file_write_action",
"//src/main/java/com/google/devtools/build/lib/analysis:actions/compression",
"//src/main/java/com/google/devtools/build/lib/analysis:actions/custom_command_line",
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTest.java
index ff01b59..c960aa9 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTest.java
@@ -27,6 +27,7 @@
import com.google.devtools.build.lib.actions.ActionInput;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.CommandLine;
+import com.google.devtools.build.lib.actions.ExecutionRequirements.WorkerProtocolFormat;
import com.google.devtools.build.lib.actions.ParamFileInfo;
import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
import com.google.devtools.build.lib.actions.RunfilesSupplier;
@@ -506,6 +507,32 @@
}
@Test
+ public void testWorkerProtocolFormat_defaultIsProto() throws Exception {
+ SpawnAction spawn =
+ createWorkerSupportSpawn(ImmutableMap.<String, String>of("supports-workers", "1"));
+ assertThat(Spawns.getWorkerProtocolFormat(spawn.getSpawn()))
+ .isEqualTo(WorkerProtocolFormat.PROTO);
+ }
+
+ @Test
+ public void testWorkerProtocolFormat_explicitProto() throws Exception {
+ SpawnAction spawn =
+ createWorkerSupportSpawn(
+ ImmutableMap.<String, String>of("supports-workers", "1", "worker-protocol", "proto"));
+ assertThat(Spawns.getWorkerProtocolFormat(spawn.getSpawn()))
+ .isEqualTo(WorkerProtocolFormat.PROTO);
+ }
+
+ @Test
+ public void testWorkerProtocolFormat_explicitJson() throws Exception {
+ SpawnAction spawn =
+ createWorkerSupportSpawn(
+ ImmutableMap.<String, String>of("supports-workers", "1", "worker-protocol", "json"));
+ assertThat(Spawns.getWorkerProtocolFormat(spawn.getSpawn()))
+ .isEqualTo(WorkerProtocolFormat.JSON);
+ }
+
+ @Test
public void testWorkerMnemonicDefault() throws Exception {
SpawnAction defaultMnemonicSpawn = createWorkerSupportSpawn(ImmutableMap.<String, String>of());
assertThat(Spawns.getWorkerKeyMnemonic(defaultMnemonicSpawn.getSpawn()))