Trabajadores multiplex (función experimental)

Informar un problema Ver código fuente Nocturno · 8.4 · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

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

Los trabajadores de multiplexación 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 multiplexados que se comuniquen con el mismo proceso de trabajador, que luego puede controlar las solicitudes en paralelo. En lenguajes como Java y Scala, esto ahorra tiempo de inicio de la JVM y 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 ciertas mnemónicas 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 multiplexados, 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 llave. Bazel usa el código hash de la clave (compuesto por variables de entorno, la raíz de ejecución y la mnemónica) para determinar qué WorkerMultiplexer usar. Los WorkerProxy se comunican con el mismo WorkerMultiplexer si tienen el mismo código hash. Por lo tanto, si se supone que las variables de entorno y la raíz de ejecución son las mismas en una sola invocación de Bazel, cada mnemónico único solo puede tener un proceso de WorkerMultiplexer y un proceso de trabajador. La cantidad total de trabajadores, incluidos los trabajadores habituales y los WorkerProxy, sigue limitada por --worker_max_instances.

Cómo escribir reglas compatibles con el multiplexado

El proceso de trabajador de la regla debe ser de varios subprocesos para aprovechar los trabajadores de multiplexación. Protobuf permite que un conjunto de reglas analice una sola solicitud, aunque haya varias solicitudes acumulándose en el flujo. Cada vez que el proceso de trabajador analiza una solicitud de la transmisión, debe controlar la solicitud en un nuevo subproceso. Debido a que diferentes subprocesos podrían completar y escribir en el flujo al mismo tiempo, el proceso de trabajador debe asegurarse de que las respuestas se escriban de forma atómica (los mensajes no se superpongan). Las respuestas deben contener el request_id de la solicitud que están controlando.

Cómo controlar la salida de multiplex

Los trabajadores de multiplexación deben tener más cuidado al manipular su producción que los trabajadores de simplex. Todo lo que se envíe a stderr se registrará en un solo archivo de registro compartido entre todos los objetos 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 ese resultado en el campo output de WorkResponse, ya que eso podría mostrarle al usuario fragmentos de resultados dañados. Si tu herramienta solo envía resultados orientados al usuario a stdout o stderr, deberás cambiar ese comportamiento antes de habilitar los trabajadores de multiplexación.

Cómo habilitar trabajadores de multiplexación

Los trabajadores de multiplexación no están habilitados de forma predeterminada. Un conjunto de reglas puede activar trabajadores de multiplexación 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 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 se configuran ambos. Puedes desactivar los trabajadores de multiplexación de forma global pasando --noworker_multiplex.

Se recomienda que un conjunto de reglas use trabajadores de multiplexación si es posible, para reducir la presión de la memoria y mejorar el rendimiento. Sin embargo, los trabajadores de multiplexación no son compatibles con la ejecución dinámica, a menos que implementen el aislamiento de multiplexación. Si intentas ejecutar trabajadores de multiplexación sin zona de pruebas con ejecución dinámica, se usarán de forma silenciosa trabajadores de multiplexación única con zona de pruebas.

Zona de pruebas de multiplex

Los trabajadores de multiplexación se pueden ejecutar en un entorno de pruebas agregando compatibilidad explícita para ellos en las implementaciones de trabajadores. Si bien el aislamiento de procesos de trabajo de un solo plex puede realizarse ejecutando cada proceso de trabajo en su propio aislamiento, los procesos de trabajo de multiplex comparten el directorio de trabajo del proceso entre varias solicitudes paralelas. Para permitir el aislamiento de los trabajadores de multiplexación, el trabajador debe admitir la lectura y escritura en un subdirectorio especificado en cada solicitud, en lugar de hacerlo directamente en su directorio de trabajo.

Para admitir el aislamiento de zona de pruebas múltiple, 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 no cambian con respecto a una solicitud que no se encuentra en el entorno 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 las que se encuentran en los archivos especificados en los argumentos (como los argumentos "argfile").

Una vez que un trabajador admite el aislamiento de múltiples procesos, el conjunto de reglas puede declarar esta compatibilidad agregando supports-multiplex-sandboxing al execution_requirements de una acción. Luego, Bazel usará el aislamiento de zona de pruebas múltiplex si se pasa la marca --experimental_worker_multiplex_sandboxing o si se usa el trabajador con la ejecución dinámica.

Los archivos de trabajo de un trabajador de multiplexación en 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 y en tools, executable o runfiles.