Trabajadores multiplex (función experimental)

En esta página, se describen los trabajadores multiplex, cómo escribir reglas compatibles con multiplex y soluciones alternativas para ciertas limitaciones.

Los trabajadores multiplex permiten que Bazel controle varias solicitudes con un solo proceso de trabajador. En el caso de los trabajadores de subprocesos múltiples, Bazel puede usar menos recursos para lograr el mismo rendimiento o uno mejor. Por ejemplo, en lugar de tener un proceso de trabajador por trabajador, Bazel puede tener cuatro trabajadores multiplex que se comuniquen con el mismo proceso de trabajador, que luego puede controlar las solicitudes en paralelo. Para lenguajes como Java y Scala, esto ahorra tiempo de preparación de JVM y tiempo de compilación 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 de trabajador. Para ciertos mnemónicos que pueden ejecutar procesos en paralelo, Bazel obtiene un WorkerProxy del grupo de trabajadores. El WorkerProxy reenvía las solicitudes al proceso de trabajador de forma secuencial junto con un request_id. El proceso de trabajador procesa la solicitud y envía respuestas al WorkerMultiplexer. Cuando el WorkerMultiplexer recibe una respuesta, analiza el request_id y, luego, reenvía las respuestas al WorkerProxy correcto. Al igual que con los trabajadores no multiplex, toda la comunicación se realiza a través de la entrada y salida estándar, pero la herramienta no puede usar stderr para la salida visible 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 el mnemónico) para determinar qué WorkerMultiplexer usar. Los WorkerProxy se comunican con el mismo WorkerMultiplexer si tienen el mismo código hash. Por lo tanto, suponiendo que las variables de entorno y la raíz de ejecución sean las mismas en una sola invocación de Bazel, cada mnemónico único solo puede tener un WorkerMultiplexer y un proceso de trabajador. La cantidad total de trabajadores, incluidos los trabajadores habituales y los WorkerProxy, aún está limitada por --worker_max_instances.

Escribe reglas compatibles con multiplex

El proceso de trabajador de la regla debe tener varios subprocesos para aprovechar los trabajadores multiplex. Protobuf permite que un conjunto de reglas analice una sola solicitud, aunque puede haber varias solicitudes acumuladas en la transmisión. Cada vez que el proceso de trabajador analiza una solicitud de la transmisión, debe controlar la solicitud en un subproceso nuevo. Debido a que diferentes subprocesos pueden completarse y escribir en la transmisión al mismo tiempo, el proceso de trabajador 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 controlan.

Cómo controlar la salida multiplex

Los trabajadores multiplex deben tener más cuidado con el control de su salida que los trabajadores singleplex. Todo lo que se envíe a stderr se incluirá en un solo archivo de registro compartido entre todos los WorkerProxy del mismo tipo, intercalado de forma aleatoria entre las solicitudes simultáneas. Si bien es una buena idea redireccionar stdout a stderr, no recopiles esa salida en el campo output de WorkResponse, ya que podría mostrar al usuario fragmentos de salida dañados. Si tu herramienta solo envía resultados orientados al usuario a stdout o stderr, deberás cambiar ese comportamiento antes de poder habilitar los trabajadores multiplex.

Habilita los trabajadores multiplex

Los trabajadores multiplex no están habilitados de forma predeterminada. Un conjunto de reglas puede activar los 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 habituales). Como sucede cuando se usan trabajadores habituales, se debe especificar una estrategia de trabajador, ya sea a nivel del conjunto de reglas (por ejemplo, --strategy=[some_mnemonic]=worker) o, en general, a nivel de la estrategia (por ejemplo, --dynamic_local_strategy=worker,standalone). No se necesitan marcas adicionales, y supports-multiplex-workers tiene prioridad sobre supports-workers, si ambas están configuradas. Para desactivar los trabajadores multiplex de forma global, pasa --noworker_multiplex.

Se recomienda que un conjunto de reglas use trabajadores multiplex 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 la zona de pruebas multiplex. Si intentas ejecutar trabajadores multiplex sin zona de pruebas con ejecución dinámica, se usarán trabajadores singleplex con zona de pruebas en su lugar.

Zona de pruebas multiplex

Los trabajadores multiplex se pueden colocar en zona de pruebas si se agrega compatibilidad explícita para ellos en las implementaciones de trabajadores. Si bien la zona de pruebas de trabajadores singleplex se puede realizar ejecutando cada proceso de 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, el trabajador debe admitir la lectura y la escritura en un subdirectorio especificado en cada solicitud, en lugar de 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 lecturas y escrituras de archivos. Si bien los campos arguments y inputs permanecen sin cambios desde una solicitud sin zona de pruebas, las entradas reales son relativas a sandbox_dir. El trabajador debe traducir las rutas de acceso de archivos que se encuentran en arguments y inputs para leer desde esta ruta de acceso modificada, y también debe escribir todas las salidas en relación con sandbox_dir. Esto incluye rutas de acceso como '.', así como rutas de acceso que se encuentran en archivos especificados en los argumentos (como los 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. Luego, 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 con zona de pruebas siguen siendo relativos al directorio de trabajo del proceso de trabajador. Por lo tanto, si un archivo se usa para ejecutar el trabajador y como entrada, se debe especificar como entrada en el argumento flagfile, así como en tools, executable o runfiles.