Multiplex-Worker (experimentelle Funktion)

Auf dieser Seite werden Multiplex-Worker, das Schreiben von Multiplex-kompatiblen Regeln und Problemumgehungen für bestimmte Einschränkungen beschrieben.

Multiplex-Worker ermöglichen es Bazel, mehrere Anfragen mit einem einzigen Worker-Prozess zu bearbeiten. Bei Multi-Thread-Workern kann Bazel weniger Ressourcen verwenden, um dieselbe oder eine bessere Leistung zu erzielen. Statt einen Worker-Prozess pro Worker zu erstellen, können in Bazel beispielsweise vier Multiple-Worker-Worker mit demselben Worker-Prozess kommunizieren, der Anfragen dann parallel verarbeiten kann. Bei Sprachen wie Java und Scala spart dies die JVM-Aufwärm- und JIT-Kompilierungszeit und ermöglicht generell die Verwendung eines gemeinsamen Caches für alle Worker desselben Typs.

Übersicht

Zwischen dem Bazel-Server und dem Worker-Prozess gibt es zwei Ebenen. Für bestimmte Mechanismen, die Prozesse parallel ausführen können, ruft Bazel WorkerProxy aus dem Worker-Pool ab. Der WorkerProxy leitet die Anfragen zusammen mit einem request_id nacheinander an den Worker-Prozess weiter und der Worker-Prozess verarbeitet die Anfrage und sendet Antworten an die WorkerMultiplexer. Wenn WorkerMultiplexer eine Antwort empfängt, wird die request_id geparst und die Antworten an die richtige WorkerProxy zurückgesendet. Wie bei nicht Multiplex-Workern erfolgt die gesamte Kommunikation über Standard-In-/Out-Vorgänge, aber das Tool kann nicht einfach nur stderr für von Nutzern sichtbare Ausgaben verwenden (siehe unten). aus.

Jeder Worker hat einen Schlüssel. Bazel bestimmt anhand des Hashcodes des Schlüssels (aus Umgebungsvariablen, dem Ausführungsstamm und der Hash-Datei), welche WorkerMultiplexer verwendet werden soll. WorkerProxys kommunizieren mit demselben WorkerMultiplexer, wenn sie denselben Hashcode haben. Wenn also Umgebungsvariablen und Ausführungsstamm in einem einzigen Bazel-Aufruf identisch sind, kann jede eindeutige memonische Instanz nur einen WorkerMultiplexer- und einen Worker-Prozess haben. Die Gesamtzahl der Worker, einschließlich regulärer Worker und WorkerProxy, ist weiterhin durch --worker_max_instances begrenzt.

Multiplex-kompatible Regeln schreiben

Der Worker-Prozess der Regel sollte Multithread enthalten, um von Multiplex-Workern zu profitieren. Mit Protobuf kann ein Regelsatz eine einzelne Anfrage parsen, auch wenn sich im Stream mehrere Anfragen ansammeln können. Wenn der Worker-Prozess eine Anfrage aus dem Stream parst, sollte die Anfrage in einem neuen Thread verarbeitet werden. Da ein anderer Thread gleichzeitig abschließen und in den Stream schreiben könnte, muss der Worker-Prozess sicherstellen, dass die Antworten atomar geschrieben werden (Nachrichten überschneiden sich nicht). Antworten müssen das request_id der Anfrage enthalten, die sie verarbeiten.

Multiplex-Ausgabe verarbeiten

Multiplex-Worker müssen die Ausgabe im Vergleich zu Singleplex-Workern mit Bedacht wählen. Alle an stderr gesendeten Elemente werden in eine einzige Logdatei verschoben, die von allen WorkerProxy desselben Typs gemeinsam genutzt wird und sich zwischen gleichzeitigen Anfragen zufällig verschränkt. Das Weiterleiten von stdout zu stderr ist zwar eine gute Idee, sammle diese Ausgabe aber nicht in das Feld output von WorkResponse, da dies den vom Nutzer manipulierten Teil der Ausgabe anzeigen könnte. aus. Wenn Ihr Tool nur nutzerorientierte Ausgabe an stdout oder stderr sendet, müssen Sie dieses Verhalten ändern, bevor Sie Multiplex-Worker aktivieren können.

Multiplex-Worker aktivieren

Multiplex-Worker sind standardmäßig nicht aktiviert. Ein Regelsatz kann Multiplex-Worker aktivieren, indem er das supports-multiplex-workers-Tag im execution_requirements einer Aktion verwendet (wie das supports-workers-Tag ermöglicht es, reguläre Worker zu aktivieren). Wie bei der Verwendung regulärer Worker muss eine Worker-Strategie entweder auf Regelebene (z. B. --strategy=[some_mnemonic]=worker) oder auf Strategieebene (z. B. --dynamic_local_strategy=worker,standalone.) Es sind keine zusätzlichen Flags erforderlich und supports-multiplex-workers hat Vorrang vor supports-workers, wenn beide festgelegt sind. Sie können Multiplex-Worker global deaktivieren, indem Sie --noexperimental_worker_multiplex übergeben.

Ein Regelsatz wird empfohlen, nach Möglichkeit Multiplex-Worker zu verwenden, um den Speicherdruck zu reduzieren und die Leistung zu verbessern. Multiplex-Worker sind derzeit jedoch nicht mit der dynamischen Ausführung kompatibel, es sei denn, sie implementieren Multiplex-Sandboxing. Wenn Sie versuchen, Multiplex-Worker, die nicht in einer Sandbox ausgeführt werden, mit dynamischer Ausführung auszuführen, werden stattdessen in einer Sandbox ausgeführte Singleplex-Worker verwendet.

Multiplex-Sandboxing

Multiplex-Worker können in einer Sandbox ausgeführt werden, indem sie in den Worker-Implementierungen explizit unterstützt werden. Während das Sandboxing von Singleplex-Workern möglich ist, indem jeder Worker-Prozess in seiner eigenen Sandbox ausgeführt wird, teilen sich Multiplex-Worker das Prozessarbeitsverzeichnis mit mehreren parallelen Anfragen. Damit Sandboxing von Multiplex-Workern möglich ist, muss der Worker das Lesen und Schreiben in ein in jeder Anfrage angegebenes Unterverzeichnis unterstützen und nicht direkt im Arbeitsverzeichnis.

Zur Unterstützung von Multiplex-Sandboxing muss der Worker das Feld sandbox_dir von WorkRequest verwenden und dieses als Präfix für alle Lese- und Schreibvorgänge von Dateien verwenden. Während die Felder arguments und inputs von einer Anfrage ohne Sandbox unverändert bleiben, beziehen sich die tatsächlichen Eingaben relativ auf sandbox_dir. Der Worker muss Dateipfade in arguments und inputs übersetzen, um aus diesem geänderten Pfad zu lesen, und alle Ausgaben relativ zum sandbox_dir schreiben. Dazu gehören Pfade wie ..“ sowie Pfade in Dateien, die in den Argumenten angegeben werden (z. B. "argfile“-Argumente).

Sobald ein Worker Multiplex-Sandboxing unterstützt, kann der Regelsatz diese Unterstützung deklarieren, indem supports-multiplex-sandboxing dem execution_requirements einer Aktion hinzugefügt wird. Bazel verwendet dann Multiplex-Sandboxing, wenn das Flag --experimental_worker_multiplex_sandboxing übergeben wird oder der Worker mit der dynamischen Ausführung verwendet wird.

Die Worker-Dateien eines Multiplex-Workers in einer Sandbox beziehen sich weiterhin auf das Arbeitsverzeichnis des Worker-Prozesses. Wenn eine Datei also sowohl zum Ausführen des Workers als auch als Eingabe verwendet werden muss, muss sie sowohl als Eingabe im Argument der Argumentdatei als auch in tools, executable oder als runfiles.