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()))