Trabajadores multiplex (función experimental)

Informar un problema Ver fuente Noche {/2/}}

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 maneje varias solicitudes con un solo proceso de trabajador. En el caso de los trabajadores de varios subprocesos, 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 comunican con el mismo proceso de trabajador, que luego puede manejar solicitudes en paralelo. Para lenguajes como Java y Scala, esto ahorra tiempo de preparación de JVM y de compilación de JIT y, en general, permite el uso de una caché compartida entre todos los trabajadores del mismo tipo.

Descripción general

Existen dos capas entre el servidor de Bazel y el proceso del trabajador. Para ciertos mnemotécnicos 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 manera secuencial junto con un request_id; el proceso de trabajador procesa la solicitud y envía respuestas a la 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 a través de entrada y salida estándar, pero la herramienta no puede usar solo 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 las variables de entorno, la raíz de ejecución y el nombre nemotécnico) para determinar qué WorkerMultiplexer usar. Los objetos 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 mnemotécnico único solo puede tener un proceso WorkerMultiplexer y un proceso de trabajador. La cantidad total de trabajadores, incluidos los trabajadores normales y los WorkerProxy, sigue limitada por --worker_max_instances.

Cómo escribir 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 trabajo analiza una solicitud desde la transmisión, debe controlarla en un subproceso nuevo. Debido a que diferentes subprocesos podrían completar 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 manejan.

Cómo manejar salidas multiplex

Los trabajadores multiplex deben tener más cuidado cuando controlan sus resultados que los trabajadores de un soloplex. Todo lo que se envíe a stderr irá a un único archivo de registro compartido entre todos los WorkerProxy del mismo tipo, intercalados al azar entre 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 esto podría mostrar al usuario fragmentos de resultado alterados. Si tu herramienta solo envía resultados orientados al usuario a stdout o stderr, deberás cambiar ese comportamiento para poder habilitar 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 mediante la etiqueta supports-multiplex-workers en el execution_requirements de una acción (al igual que la etiqueta supports-workers habilita trabajadores normales). Como sucede cuando se usan trabajadores normales, se debe especificar una estrategia de trabajadores, ya sea a nivel del conjunto de reglas (por ejemplo, --strategy=[some_mnemonic]=worker) o, en 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 ambas están configuradas. Si deseas desactivar los trabajadores multiplex de forma global, pasa --noexperimental_worker_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, por el momento, los trabajadores multiplex no son compatibles con la ejecución dinámica, a menos que implementen zonas de pruebas multiplex. Si intentas ejecutar trabajadores multiplex que no están en zona de pruebas con la ejecución dinámica, se usarán de forma silenciosa trabajadores de singleplex de zona de pruebas en su lugar.

Zona de pruebas multiplex

Los trabajadores multiplex pueden colocarse en una zona de pruebas agregando compatibilidad explícita con ellos en las implementaciones de los trabajadores. Si bien la zona de pruebas de trabajadores de un soloplex 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 hacerlo directamente en su directorio de trabajo.

Para admitir zonas 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 fuera de la zona de pruebas, las entradas reales son relativas a sandbox_dir. El trabajador debe traducir las rutas de acceso a los archivos que se encuentran en arguments y inputs para leer desde esta ruta modificada, y también debe escribir todos los resultados relacionados con sandbox_dir. Esto incluye rutas de acceso como “.”, así como rutas encontradas en archivos especificados en los argumentos (como "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 ejecución dinámica.

Los archivos de trabajador de un trabajador multiplex de zona de pruebas siguen estando relacionados con el directorio de trabajo del proceso trabajador. Por lo tanto, si se usa un archivo para ejecutar el trabajador y como entrada, debe especificarse como entrada en el argumento del archivo marcador y en tools, executable o runfiles.