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