ผู้ปฏิบัติงาน Multiplex (ฟีเจอร์ทดลอง)

หน้านี้อธิบายเกี่ยวกับผู้ปฏิบัติงานแบบมัลติเพล็กซ์ วิธีเขียนกฎที่เข้ากันได้กับมัลติเพล็กซ์ และวิธีแก้ปัญหาข้อจำกัดบางอย่าง

ผู้ปฏิบัติงานแบบมัลติเพล็กซ์ช่วยให้ Bazel จัดการคำขอหลายรายการด้วยกระบวนการของผู้ปฏิบัติงานเดียวได้ สำหรับผู้ปฏิบัติงานแบบมัลติเธรด Bazel สามารถใช้ทรัพยากรน้อยลงเพื่อให้ได้ประสิทธิภาพเท่าเดิมหรือดีขึ้น เช่น แทนที่จะมีกระบวนการของผู้ปฏิบัติงาน 1 รายการต่อผู้ปฏิบัติงาน 1 รายการ Bazel สามารถมีผู้ปฏิบัติงานแบบมัลติเพล็กซ์ 4 รายการที่สื่อสารกับกระบวนการของผู้ปฏิบัติงานเดียวกัน ซึ่งจะจัดการคำขอแบบขนานได้ สำหรับภาษาอย่าง Java และ Scala การดำเนินการนี้จะช่วยประหยัดเวลาในการวอร์มอัป JVM และเวลาในการคอมไพล์ JIT และโดยทั่วไปจะช่วยให้ใช้แคชที่แชร์ร่วมกันระหว่างผู้ปฏิบัติงานทุกรายที่มีประเภทเดียวกันได้

ภาพรวม

มี 2 เลเยอร์ระหว่างเซิร์ฟเวอร์ Bazel กับกระบวนการของผู้ปฏิบัติงาน สำหรับคำย่อบางคำที่สามารถเรียกใช้กระบวนการแบบขนานได้ Bazel จะรับ WorkerProxy จากพูลของผู้ปฏิบัติงาน WorkerProxy จะส่งต่อคำขอไปยังกระบวนการของผู้ปฏิบัติงานตามลำดับพร้อมกับ request_id กระบวนการของผู้ปฏิบัติงานจะประมวลผลคำขอและส่งการตอบกลับไปยัง WorkerMultiplexer เมื่อ WorkerMultiplexer ได้รับการตอบกลับ ระบบจะแยกวิเคราะห์ request_id แล้วส่งต่อการตอบกลับกลับไปยัง WorkerProxy ที่ถูกต้อง เช่นเดียวกับผู้ปฏิบัติงานที่ไม่ใช่แบบมัลติเพล็กซ์ การสื่อสารทั้งหมด จะดำเนินการผ่านอินพุต/เอาต์พุตมาตรฐาน แต่เครื่องมือไม่สามารถใช้ stderr สำหรับเอาต์พุตที่ผู้ใช้มองเห็นได้ (ดูด้านล่าง)

ผู้ปฏิบัติงานแต่ละรายจะมีคีย์ Bazel ใช้รหัสแฮชของคีย์ (ประกอบด้วยตัวแปรสภาพแวดล้อม รูทการดำเนินการ และคำย่อ) เพื่อกำหนด WorkerMultiplexer ที่จะใช้ WorkerProxy จะสื่อสารกับ WorkerMultiplexer เดียวกันหากมีรหัสแฮชเดียวกัน ดังนั้น สมมติว่าตัวแปรสภาพแวดล้อมและรูทการดำเนินการเหมือนกันในการเรียกใช้ Bazel ครั้งเดียว คำย่อที่ไม่ซ้ำกันแต่ละคำจะมี WorkerMultiplexer และกระบวนการของผู้ปฏิบัติงานได้เพียงรายการเดียว จำนวนผู้ปฏิบัติงานทั้งหมด รวมถึงผู้ปฏิบัติงานทั่วไปและ WorkerProxy ยังคงถูกจำกัดโดย --worker_max_instances

การเขียนกฎที่เข้ากันได้กับมัลติเพล็กซ์

กระบวนการของผู้ปฏิบัติงานของกฎควรเป็นแบบมัลติเธรดเพื่อใช้ประโยชน์จากผู้ปฏิบัติงานแบบมัลติเพล็กซ์ Protobuf อนุญาตให้ชุดกฎแยกวิเคราะห์คำขอเดียวได้ แม้ว่าจะมีคำขอหลายรายการสะสมอยู่ในสตรีม เมื่อใดก็ตามที่กระบวนการของผู้ปฏิบัติงานแยกวิเคราะห์คำขอจากสตรีม กระบวนการดังกล่าวควรจัดการคำขอในเธรดใหม่ เนื่องจากเธรดต่างๆ อาจดำเนินการเสร็จและเขียนลงในสตรีมพร้อมกัน กระบวนการของผู้ปฏิบัติงานจึงต้องตรวจสอบว่าการตอบกลับเขียนขึ้นแบบอะตอมมิก (ข้อความไม่ทับซ้อนกัน) การตอบกลับต้องมี request_id ของคำขอที่กำลังจัดการ

การจัดการเอาต์พุตแบบมัลติเพล็กซ์

ผู้ปฏิบัติงานแบบมัลติเพล็กซ์ต้องระมัดระวังในการจัดการเอาต์พุตมากกว่าผู้ปฏิบัติงานแบบซิงเกิลเพล็กซ์ ทุกสิ่งที่ส่งไปยัง stderr จะไปอยู่ในไฟล์บันทึกเดียวที่แชร์ระหว่าง WorkerProxy ทั้งหมดที่มีประเภทเดียวกัน โดยจะสลับกันแบบสุ่มระหว่างคำขอที่เกิดขึ้นพร้อมกัน แม้ว่าการเปลี่ยนเส้นทาง stdout ไปยัง stderr จะเป็นความคิดที่ดี แต่ก็ไม่ควรเก็บเอาต์พุตนั้นไว้ในช่อง output ของ WorkResponse เนื่องจากอาจแสดงเอาต์พุตที่เสียหายต่อผู้ใช้ หากเครื่องมือของคุณส่งเอาต์พุตที่มุ่งเน้นผู้ใช้ไปยัง stdout หรือ stderr เท่านั้น คุณจะต้องเปลี่ยนลักษณะการทำงานนั้นก่อนจึงจะเปิดใช้ผู้ปฏิบัติงานแบบมัลติเพล็กซ์ได้

การเปิดใช้ผู้ปฏิบัติงานแบบมัลติเพล็กซ์

ระบบจะไม่ได้เปิดใช้ผู้ปฏิบัติงานแบบมัลติเพล็กซ์โดยค่าเริ่มต้น ชุดกฎสามารถเปิดใช้ผู้ปฏิบัติงานแบบมัลติเพล็กซ์ได้โดยใช้แท็ก supports-multiplex-workers ใน execution_requirements ของการดำเนินการ (เช่นเดียวกับแท็ก supports-workers ที่เปิดใช้ผู้ปฏิบัติงานทั่วไป) เช่นเดียวกับกรณีที่ใช้ผู้ปฏิบัติงานทั่วไป คุณต้องระบุกลยุทธ์ของผู้ปฏิบัติงาน ไม่ว่าจะที่ระดับชุดกฎ (เช่น --strategy=[some_mnemonic]=worker) หรือโดยทั่วไปที่ระดับกลยุทธ์ (เช่น --dynamic_local_strategy=worker,standalone) ไม่จำเป็นต้องใช้แฟล็กเพิ่มเติม และ supports-multiplex-workers จะมีความสำคัญเหนือกว่า supports-workers หากมีการตั้งค่าทั้ง 2 อย่าง คุณสามารถปิดใช้ผู้ปฏิบัติงานแบบมัลติเพล็กซ์ทั่วโลกได้โดยส่ง --noworker_multiplex

เราขอแนะนำให้ชุดกฎใช้ผู้ปฏิบัติงานแบบมัลติเพล็กซ์หากเป็นไปได้ เพื่อลดการใช้หน่วยความจำ และปรับปรุงประสิทธิภาพ อย่างไรก็ตาม ปัจจุบันผู้ปฏิบัติงานแบบมัลติเพล็กซ์ยังใช้ร่วมกับ การดำเนินการแบบไดนามิกไม่ได้ เว้นแต่จะมีการใช้แซนด์บ็อกซ์แบบมัลติเพล็กซ์ การพยายามเรียกใช้ผู้ปฏิบัติงานแบบมัลติเพล็กซ์ที่ไม่ใช่แซนด์บ็อกซ์ด้วยการดำเนินการแบบไดนามิกจะใช้ผู้ปฏิบัติงานแบบซิงเกิลเพล็กซ์ที่เป็นแซนด์บ็อกซ์แทนโดยไม่มีการแจ้งเตือน

แซนด์บ็อกซ์แบบมัลติเพล็กซ์

ผู้ปฏิบัติงานแบบมัลติเพล็กซ์สามารถใช้แซนด์บ็อกซ์ได้โดยเพิ่มการรองรับอย่างชัดเจนในการใช้งานของผู้ปฏิบัติงาน แม้ว่าการใช้แซนด์บ็อกซ์กับผู้ปฏิบัติงานแบบซิงเกิลเพล็กซ์จะทำได้โดยการเรียกใช้กระบวนการของผู้ปฏิบัติงานแต่ละรายในแซนด์บ็อกซ์ของตนเอง แต่ผู้ปฏิบัติงานแบบมัลติเพล็กซ์จะแชร์ไดเรกทอรีการทำงานของกระบวนการระหว่างคำขอแบบขนานหลายรายการ หากต้องการอนุญาตให้ใช้แซนด์บ็อกซ์กับผู้ปฏิบัติงานแบบมัลติเพล็กซ์ ผู้ปฏิบัติงานต้องรองรับการอ่านและการเขียนไปยังไดเรกทอรีย่อยที่ระบุในคำขอแต่ละรายการ แทนที่จะอ่านและเขียนในไดเรกทอรีการทำงานโดยตรง

หากต้องการรองรับแซนด์บ็อกซ์แบบมัลติเพล็กซ์ ผู้ปฏิบัติงานต้องใช้ช่อง sandbox_dir จาก WorkRequest และใช้ช่องดังกล่าวเป็นคำนำหน้าสำหรับการอ่านและการเขียนไฟล์ทั้งหมด แม้ว่าช่อง arguments และ inputs จะยังคงเหมือนเดิมจากคำขอที่ไม่ใช่แซนด์บ็อกซ์ แต่ข้อมูลอินพุตจริงจะสัมพันธ์กับ sandbox_dir ผู้ปฏิบัติงานต้องแปลเส้นทางไฟล์ที่พบใน arguments และ inputs เพื่ออ่านจากเส้นทางที่แก้ไขนี้ และต้องเขียนเอาต์พุตทั้งหมดที่สัมพันธ์กับ sandbox_dir ด้วย ซึ่งรวมถึงเส้นทางต่างๆ เช่น '.' รวมถึงเส้นทางที่พบในไฟล์ที่ระบุ ในอาร์กิวเมนต์ (เช่น "argfile" อาร์กิวเมนต์)

เมื่อผู้ปฏิบัติงานรองรับแซนด์บ็อกซ์แบบมัลติเพล็กซ์แล้ว ชุดกฎจะประกาศการรองรับนี้ได้โดยเพิ่ม supports-multiplex-sandboxing ลงใน execution_requirements ของการดำเนินการ จากนั้น Bazel จะใช้แซนด์บ็อกซ์แบบมัลติเพล็กซ์หากมีการส่งแฟล็ก --experimental_worker_multiplex_sandboxing หรือหากมีการใช้ผู้ปฏิบัติงานกับการดำเนินการแบบไดนามิก

ไฟล์ของผู้ปฏิบัติงานแบบมัลติเพล็กซ์ที่เป็นแซนด์บ็อกซ์จะยังคงสัมพันธ์กับไดเรกทอรีการทำงานของกระบวนการของผู้ปฏิบัติงาน ดังนั้น หากมีการใช้ไฟล์ทั้งสำหรับการเรียกใช้ผู้ปฏิบัติงานและเป็นอินพุต คุณต้องระบุไฟล์ดังกล่าวทั้งเป็นอินพุตในอาร์กิวเมนต์แฟล็กไฟล์ รวมถึงใน tools, executable หรือ runfiles