หน้านี้อธิบายเกี่ยวกับ Worker แบบมัลติเพล็กซ์ วิธีเขียนกฎที่เข้ากันได้กับมัลติเพล็กซ์ และวิธีแก้ปัญหาข้อจำกัดบางอย่าง
Worker แบบมัลติเพล็กซ์ช่วยให้ Bazel จัดการคำขอหลายรายการด้วยกระบวนการ Worker เดียวได้ สำหรับ Worker แบบมัลติเธรด Bazel สามารถใช้ทรัพยากรน้อยลงเพื่อให้ได้ประสิทธิภาพเท่าเดิมหรือดีขึ้น เช่น แทนที่จะมีกระบวนการ Worker 1 รายการต่อ Worker 1 รายการ Bazel สามารถมี Worker แบบมัลติเพล็กซ์ 4 รายการที่สื่อสารกับกระบวนการ Worker เดียวกัน ซึ่งจะจัดการคำขอแบบขนานได้ สำหรับภาษาอย่าง Java และ Scala การดำเนินการนี้จะช่วยประหยัดเวลาในการวอร์มอัป JVM และเวลาในการคอมไพล์ JIT และโดยทั่วไปจะอนุญาตให้ใช้แคชที่แชร์ 1 รายการระหว่าง Worker ทุกรายการที่เป็นประเภทเดียวกัน
ภาพรวม
มี 2 เลเยอร์ระหว่างเซิร์ฟเวอร์ Bazel กับกระบวนการ Worker สำหรับคำย่อบางคำที่สามารถเรียกใช้กระบวนการแบบขนานได้ Bazel จะรับ WorkerProxy จากพูล Worker WorkerProxy จะส่งต่อคำขอไปยังกระบวนการ Worker ตามลำดับพร้อมกับ request_id กระบวนการ Worker จะประมวลผลคำขอและส่งการตอบกลับไปยัง WorkerMultiplexer เมื่อ WorkerMultiplexer ได้รับการตอบกลับ ระบบจะแยกวิเคราะห์ request_id แล้วส่งต่อการตอบกลับกลับไปยัง WorkerProxy ที่ถูกต้อง การสื่อสารทั้งหมดจะดำเนินการผ่านอินพุต/เอาต์พุตมาตรฐานเช่นเดียวกับ Worker ที่ไม่ใช่แบบมัลติเพล็กซ์ แต่เครื่องมือไม่สามารถใช้
stderr สำหรับเอาต์พุตที่ผู้ใช้มองเห็นได้ (ดูด้านล่าง)
Worker แต่ละรายการจะมีคีย์ Bazel ใช้รหัสแฮชของคีย์ (ประกอบด้วยตัวแปรสภาพแวดล้อม รูทการดำเนินการ และคำย่อ) เพื่อกำหนด WorkerMultiplexer ที่จะใช้ WorkerProxy จะสื่อสารกับ WorkerMultiplexer เดียวกันหากมีรหัสแฮชเดียวกัน ดังนั้น สมมติว่าตัวแปรสภาพแวดล้อมและรูทการดำเนินการเหมือนกันในการเรียกใช้ Bazel ครั้งเดียว คำย่อที่ไม่ซ้ำกันแต่ละคำจะมี WorkerMultiplexer และกระบวนการ Worker ได้เพียงรายการเดียว จำนวน Worker ทั้งหมด รวมถึง Worker ปกติและ WorkerProxy ยังคงถูกจำกัดโดย --worker_max_instances
การเขียนกฎที่เข้ากันได้กับมัลติเพล็กซ์
กระบวนการ Worker ของกฎควรเป็นแบบมัลติเธรดเพื่อใช้ประโยชน์จาก Worker แบบมัลติเพล็กซ์ Protobuf อนุญาตให้ชุดกฎแยกวิเคราะห์คำขอเดียวได้ แม้ว่าจะมีคำขอหลายรายการสะสมอยู่ในสตรีม เมื่อใดก็ตามที่กระบวนการ Worker แยกวิเคราะห์คำขอจากสตรีม กระบวนการดังกล่าวควรจัดการคำขอในเทรดใหม่ เนื่องจากเธรดต่างๆ อาจดำเนินการเสร็จและเขียนลงในสตรีมพร้อมกัน กระบวนการ Worker จึงต้องตรวจสอบว่าการตอบกลับเขียนขึ้นแบบอะตอมมิก (ข้อความไม่ทับซ้อนกัน) การตอบกลับต้องมี request_id ของคำขอที่กำลังจัดการ
การจัดการเอาต์พุตแบบมัลติเพล็กซ์
Worker แบบมัลติเพล็กซ์ต้องระมัดระวังในการจัดการเอาต์พุตมากกว่า Worker แบบซิงเกิลเพล็กซ์ ทุกสิ่งที่ส่งไปยัง stderr จะไปอยู่ในไฟล์บันทึกเดียวที่แชร์ระหว่าง WorkerProxy ทั้งหมดที่เป็นประเภทเดียวกัน โดยจะสลับกันแบบสุ่มระหว่างคำขอที่เกิดขึ้นพร้อมกัน แม้ว่าการเปลี่ยนเส้นทาง stdout ไปยัง stderr จะเป็นความคิดที่ดี แต่ก็ไม่ควรเก็บเอาต์พุตนั้นไว้ในช่อง output ของ WorkResponse เนื่องจากอาจแสดงเอาต์พุตที่เสียหายต่อผู้ใช้
หากเครื่องมือของคุณส่งเอาต์พุตที่มุ่งเน้นผู้ใช้ไปยัง stdout หรือ stderr เท่านั้น คุณจะต้องเปลี่ยนลักษณะการทำงานดังกล่าวก่อนจึงจะเปิดใช้ Worker แบบมัลติเพล็กซ์ได้
การเปิดใช้ Worker แบบมัลติเพล็กซ์
ระบบจะไม่ได้เปิดใช้ Worker แบบมัลติเพล็กซ์โดยค่าเริ่มต้น ชุดกฎสามารถเปิดใช้ Worker แบบมัลติเพล็กซ์ได้โดยใช้แท็ก supports-multiplex-workers ใน execution_requirements ของการดำเนินการ (เช่นเดียวกับแท็ก supports-workers ที่เปิดใช้ Worker ปกติ) เช่นเดียวกับกรณีที่ใช้ Worker ปกติ คุณต้องระบุกลยุทธ์ Worker ไม่ว่าจะที่ระดับชุดกฎ (เช่น --strategy=[some_mnemonic]=worker) หรือโดยทั่วไปที่ระดับกลยุทธ์ (เช่น --dynamic_local_strategy=worker,standalone) ไม่จำเป็นต้องใช้แฟล็กเพิ่มเติม และ supports-multiplex-workers จะมีความสำคัญเหนือกว่า supports-workers หากมีการตั้งค่าทั้ง 2 อย่าง คุณสามารถปิดใช้ Worker แบบมัลติเพล็กซ์ทั่วโลกได้โดยส่ง --noworker_multiplex
เราขอแนะนำให้ชุดกฎใช้ Worker แบบมัลติเพล็กซ์หากเป็นไปได้ เพื่อลดการใช้หน่วยความจำ และปรับปรุงประสิทธิภาพ อย่างไรก็ตาม ปัจจุบัน Worker แบบมัลติเพล็กซ์ยังใช้ร่วมกับ การดำเนินการแบบ ไดนามิก ไม่ได้ เว้นแต่จะมีการใช้ แซนด์บ็อกซ์แบบมัลติเพล็กซ์ การพยายามเรียกใช้ Worker แบบมัลติเพล็กซ์ที่ไม่ได้ใช้แซนด์บ็อกซ์ด้วยการดำเนินการแบบไดนามิกจะใช้ Worker แบบซิงเกิลเพล็กซ์ที่ใช้แซนด์บ็อกซ์แทนโดยไม่มีการแจ้งเตือน
แซนด์บ็อกซ์แบบมัลติเพล็กซ์
คุณสามารถใช้แซนด์บ็อกซ์กับ Worker แบบมัลติเพล็กซ์ได้โดยเพิ่มการรองรับอย่างชัดเจนในการใช้งาน Worker แม้ว่าการใช้แซนด์บ็อกซ์กับ Worker แบบซิงเกิลเพล็กซ์จะทำได้โดยการเรียกใช้กระบวนการ Worker แต่ละรายการในแซนด์บ็อกซ์ของตัวเอง แต่ Worker แบบมัลติเพล็กซ์จะแชร์ไดเรกทอรีการทำงานของกระบวนการระหว่างคำขอแบบขนานหลายรายการ หากต้องการอนุญาตให้ใช้แซนด์บ็อกซ์กับ Worker แบบมัลติเพล็กซ์ Worker ต้องรองรับการอ่านและการเขียนไปยังไดเรกทอรีย่อยที่ระบุในคำขอแต่ละรายการ แทนที่จะอ่านและเขียนในไดเรกทอรีการทำงานโดยตรง
หากต้องการรองรับแซนด์บ็อกซ์แบบมัลติเพล็กซ์ Worker ต้องใช้ช่อง sandbox_dir จาก WorkRequest และใช้ช่องดังกล่าวเป็นคำนำหน้าสำหรับการอ่านและการเขียนไฟล์ทั้งหมด
แม้ว่าช่อง arguments และ inputs จะยังคงเหมือนเดิมจากคำขอที่ไม่ได้ใช้แซนด์บ็อกซ์ แต่ข้อมูลอินพุตจริงจะสัมพันธ์กับ sandbox_dir Worker ต้องแปลเส้นทางไฟล์ที่พบใน arguments และ inputs เพื่ออ่านจากเส้นทางที่แก้ไขนี้ และต้องเขียนเอาต์พุตทั้งหมดที่สัมพันธ์กับ sandbox_dir ด้วย
ซึ่งรวมถึงเส้นทางต่างๆ เช่น '.' รวมถึงเส้นทางที่พบในไฟล์ที่ระบุ
ในอาร์กิวเมนต์ (เช่น "argfile" อาร์กิวเมนต์)
เมื่อ Worker รองรับแซนด์บ็อกซ์แบบมัลติเพล็กซ์แล้ว ชุดกฎจะประกาศการรองรับนี้ได้โดยเพิ่ม supports-multiplex-sandboxing ลงใน execution_requirements ของการดำเนินการ จากนั้น Bazel จะใช้แซนด์บ็อกซ์แบบมัลติเพล็กซ์หากมีการส่งแฟล็ก --experimental_worker_multiplex_sandboxing หรือหากใช้ Worker กับการดำเนินการแบบไดนามิก
ไฟล์ Worker ของ Worker แบบมัลติเพล็กซ์ที่ใช้แซนด์บ็อกซ์จะยังคงสัมพันธ์กับไดเรกทอรีการทำงานของกระบวนการ Worker ดังนั้น หากใช้ไฟล์ทั้งสำหรับการเรียกใช้ Worker และเป็นอินพุต คุณต้องระบุไฟล์ดังกล่าวทั้งเป็นอินพุตในอาร์กิวเมนต์แฟล็กไฟล์ รวมถึงใน tools, executable หรือ runfiles