-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Description
Description of the bug:
Bazel allows rule authors to change how messages to/from persistent workers are encoded by setting the requires-worker-protocol execution property to either json or proto. Using json allows a worker to avoid depending on the protobuf runtime, which can be quite large. This works great for local actions, but it this setting doesn't seem to be communicated to a remote execution service, so a service may try to run worker actions with proto, even if the worker only supports json. Only persistentWorkerKey is communicated via the Platform proto.
Could we standardize a new platform property name (perhaps simply requires-worker-protocol), then send that to the remote server if an action has it set?
Which category does this issue belong to?
Remote Execution
What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.
Here's a minimal Python worker that communicates in json. bazel build :scratch succeeds locally but fails remotely with EngFlow.
-- BUILD --
load("@rules_python//python:defs.bzl", "py_binary")
load(":def.bzl", "work")
work(
name = "scratch",
out = "scratch.txt",
value = "1",
)
py_binary(
name = "worker",
srcs = ["worker.py"],
)
-- def.bzl --
def _work_impl(ctx):
flags_file = ctx.actions.declare_file(ctx.label.name + ".args")
args = ["/bin/bash", "-c", "echo '{}' >'{}'".format(ctx.attr.value, ctx.outputs.out.path)]
ctx.actions.write(flags_file, "\n".join(args))
ctx.actions.run(
mnemonic = "Work",
inputs = [flags_file],
outputs = [ctx.outputs.out],
arguments = ["@{}".format(flags_file.path)],
executable = ctx.executable._worker,
execution_requirements = {
"supports-workers": "1",
"requires-worker-protocol": "json",
},
)
work = rule(
implementation = _work_impl,
attrs = {
"value": attr.string(mandatory = True),
"out": attr.output(mandatory = True),
"_worker": attr.label(
default = ":worker",
executable = True,
cfg = "exec",
),
},
)
-- worker.py --
#!/usr/bin/env python
import argparse
import json
import os
import os.path
import subprocess
import sys
def main():
parser = argparse.ArgumentParser(
prog = "run_api_worker",
description = "Persistnet worker for running commands within a repo",
)
parser.add_argument("--persistent_worker", action='store_true')
args = parser.parse_args()
if not args.persistent_worker:
sys.stderr.write("--persistent_worker is mandatory")
sys.exit(1)
for line in sys.stdin:
line = line.strip()
if not line:
continue
request = json.loads(line)
response = serve_request(request)
json.dump(response, sys.stdout)
sys.stdout.write('\n')
sys.stdout.flush()
def serve_request(request):
wd = os.getcwd()
if "sandbox_dir" in request:
wd = os.path.join(wd, request["sandbox_dir"])
try:
proc = subprocess.run(
request["arguments"],
cwd = wd,
stdout = subprocess.PIPE,
stderr = subprocess.STDOUT)
return {
"exit_code": proc.returncode,
"output": proc.stdout.decode("utf-8"),
}
except Exception as e:
return {
"exit_code": -1,
"output": str(e),
}
if __name__ == "__main__":
main()
Which operating system are you running Bazel on?
macOS
What is the output of bazel info release?
release 10.0.0-pre.20260114.1
If bazel info release returns development version or (@non-git), tell us how you built Bazel.
No response
What's the output of git remote get-url origin; git rev-parse HEAD ?
If this is a regression, please try to identify the Bazel commit where the bug was introduced with bazelisk --bisect.
No response
Have you found anything relevant by searching the web?
No response
Any other information, logs, or outputs that you want to share?
No response