En esta página, se describen los trabajadores multiplex, cómo escribir reglas compatibles con ellos y las soluciones alternativas para ciertas limitaciones.
Los trabajadores multiplex permiten que Bazel maneje varias solicitudes con un solo proceso de trabajador. Para los trabajadores de varios subprocesos, Bazel puede usar menos recursos a fin de lograr lo mismo o un mejor rendimiento. Por ejemplo, en lugar de tener un proceso de trabajo por trabajador, Bazel puede tener cuatro trabajadores multiplexados que hablen del mismo proceso, que luego puede controlar las solicitudes en paralelo. Para lenguajes como Java y Scala, se ahorra tiempo de calentamiento de JVM y tiempo de compilación de JIT y, en general, permite usar una caché compartida entre todos los trabajadores del mismo tipo.
Descripción general
Hay dos capas entre el servidor de Bazel y el proceso del trabajador. Para
algunos mnemotécnicos que pueden ejecutar procesos en paralelo, Bazel obtiene un WorkerProxy
del
grupo de trabajadores. El WorkerProxy
reenvía las solicitudes al proceso del trabajador de manera secuencial junto con una request_id
, el proceso del trabajador procesa la solicitud y envía las respuestas al WorkerMultiplexer
. Cuando WorkerMultiplexer
recibe una respuesta, analiza el request_id
y, luego, reenvía las respuestas al WorkerProxy
correcto. Al igual que con los trabajadores no multiplexados, toda la comunicación se realiza mediante entrada y salida estándar, pero la herramienta no puede usar stderr
para resultados visibles para el usuario (consulta a continuación).
Cada trabajador tiene una clave. Bazel usa el código hash de la clave (compuesto por variables de entorno, la raíz de ejecución y la nemotécnica) para determinar qué WorkerMultiplexer
usar. Los WorkerProxy
se comunican con el mismo WorkerMultiplexer
si tienen el mismo código hash. Por lo tanto, si
suponemos que las variables de entorno y la raíz de ejecución son las mismas en una sola invocación de
Bazel, cada valor mnemotécnico único solo puede tener un proceso de
WorkerMultiplexer
y un trabajador. La cantidad total de trabajadores, incluidos los normales y
WorkerProxy
, aún está limitada por --worker_max_instances
.
Cómo escribir reglas compatibles con multiplex
El proceso de trabajador de la regla debe ser de varios subprocesos para aprovechar los multiplex. Protobuf permite que un conjunto de reglas analice una sola solicitud, aunque podrían acumularse varias solicitudes en la transmisión. Siempre que el proceso del trabajador analice una solicitud del flujo, debe manejarla en un subproceso nuevo. Debido a que diferentes subprocesos pueden completar y escribir en la transmisión al mismo tiempo, el proceso de trabajo debe asegurarse de que las respuestas se escriban de forma atómica (los mensajes no se superponen). Las respuestas deben contener el request_id
de la solicitud que están controlando.
Cómo controlar los resultados multiplex
Los trabajadores multiplex deben tener más cuidado en el manejo de su resultado que los trabajadores singleplex. Todo lo que se envíe a stderr
irá a un solo archivo de registro compartido entre todos los WorkerProxy
del mismo tipo, intercalados de forma aleatoria entre las solicitudes simultáneas. Si bien redireccionar stdout
a stderr
es una buena idea, no recopiles ese resultado en el campo output
de WorkResponse
, ya que podría mostrarle al usuario piezas alteradas del resultado.
Si tu herramienta solo envía un resultado orientado al usuario a stdout
o stderr
, deberás cambiar ese comportamiento antes de que puedas habilitar los trabajadores multiplex.
Cómo habilitar trabajadores multiplex
Los trabajadores multiplex no están habilitados de forma predeterminada. Un conjunto de reglas puede activar trabajadores multiplex con la etiqueta supports-multiplex-workers
en el execution_requirements
de una acción (al igual que la etiqueta supports-workers
habilita a los trabajadores normales). Al igual que cuando se usan trabajadores normales, se debe especificar una estrategia de trabajador, ya sea a nivel de conjunto de reglas (por ejemplo, --strategy=[some_mnemonic]=worker
) o, por lo general, a nivel de estrategia (por ejemplo, --dynamic_local_strategy=worker,standalone
). No se necesitan marcas adicionales y supports-multiplex-workers
tiene prioridad sobre supports-workers
, si se configuran ambos. Puedes desactivar los multiplexadores de forma global si pasas --noworker_multiplex
.
Se recomienda que un conjunto de reglas use multiplex trabajadores si es posible, para reducir la presión de la memoria y mejorar el rendimiento. Sin embargo, los trabajadores multiplex no son compatibles actualmente con la ejecución dinámica, a menos que implementen una zona de pruebas multiplex. En su lugar, si se intentan ejecutar trabajadores multiplex sin zona de pruebas con ejecución dinámica, se usarán trabajadores singleplex de la zona de pruebas de forma silenciosa.
Zona de pruebas multiplex
Los trabajadores multiplex se pueden poner en zona de pruebas si se le agrega asistencia explícita en las implementaciones de trabajador. Si bien la zona de pruebas del trabajador singleplex se puede realizar ejecutando el proceso de cada trabajador en su propia zona de pruebas, los trabajadores multiplex comparten el directorio de trabajo del proceso entre varias solicitudes paralelas. Para permitir la zona de pruebas de trabajadores multiplex, estos deben admitir la lectura y la escritura en un subdirectorio especificado en cada solicitud, en lugar de hacerlo directamente en su directorio de trabajo.
Para admitir la zona de pruebas multiplex, el trabajador debe usar el campo sandbox_dir
de WorkRequest
y usarlo como prefijo para todas las operaciones de lectura y escritura de archivos.
Si bien los campos arguments
y inputs
permanecen sin cambios desde una solicitud sin zona de pruebas, las entradas reales están relacionadas con sandbox_dir
. El trabajador debe traducir las rutas de acceso a archivos que se encuentran en arguments
y inputs
para leer desde esta ruta de acceso modificada, y también debe escribir todos los resultados relacionados con sandbox_dir
.
Esto incluye rutas como ".", además de las rutas de los archivos especificados en los argumentos (como argumentos "argfile").
Una vez que un trabajador admite la zona de pruebas multiplex, el conjunto de reglas puede declarar esta compatibilidad agregando supports-multiplex-sandboxing
al execution_requirements
de una acción. Bazel usará la zona de pruebas multiplex
si se pasa la marca --experimental_worker_multiplex_sandboxing
o
si el trabajador se usa con la ejecución dinámica.
Los archivos de trabajador de un trabajador multiplex de zona de pruebas siguen relacionados con el directorio de trabajo del proceso del trabajador. Por lo tanto, si un archivo se usa para ejecutar el trabajador y como entrada, debe especificarse como entrada en el argumento del archivo de marca y en tools
, executable
o runfiles
.