ผู้ปฏิบัติงานอย่างต่อเนื่องจะช่วยให้บิลด์ของคุณทำงานได้เร็วขึ้น ถ้า คุณมีการดำเนินการซ้ำๆ ในบิลด์ที่มีต้นทุนในการเริ่มต้นใช้งานสูง หรือ ประโยชน์จากการแคชข้ามการกระทำ คุณอาจต้องการใช้ ผู้ปฏิบัติงานเพื่อดำเนินการเหล่านี้
เซิร์ฟเวอร์ Bazel จะสื่อสารกับเวิร์กเกอร์โดยใช้ stdin
/stdout
โดยรองรับการใช้บัฟเฟอร์โปรโตคอลหรือสตริง JSON
การติดตั้งใช้งานผู้ดําเนินการมี 2 ส่วน ได้แก่
การทำให้พนักงาน
ผู้ปฏิบัติงานแบบถาวรต้องปฏิบัติตามข้อกำหนดบางประการ ดังนี้
- อ่านว่า
WorkRequests
จาก
stdin
- โดยจะเขียน WorkResponses (และเฉพาะ
WorkResponse
) ลงในstdout
- ยอมรับ Flag
--persistent_worker
Wrapper ต้องจดจำ แฟล็กบรรทัดคำสั่ง--persistent_worker
และทำให้ตนเองอยู่ถาวรได้ก็ต่อเมื่อ แฟล็กนั้นจะถูกส่งผ่าน หรือมิฉะนั้นก็จะต้องทำการคอมไพล์และการออกภาพเดียว
หากโปรแกรมของคุณปฏิบัติตามข้อกำหนดเหล่านี้ ก็สามารถใช้เป็นแบบถาวร ผู้ปฏิบัติงาน!
คำของาน
WorkRequest
มีรายการอาร์กิวเมนต์สำหรับเวิร์กเกอร์ รายการคู่เส้นทาง-ข้อมูลสรุปที่แสดงอินพุตที่เวิร์กเกอร์เข้าถึงได้ (ระบบไม่ได้บังคับใช้ แต่คุณใช้ข้อมูลนี้เพื่อแคชได้) และรหัสคำขอ ซึ่งจะเป็น 0 สำหรับเวิร์กเกอร์แบบ Singleplex
หมายเหตุ: แม้ว่าข้อกำหนดบัฟเฟอร์โปรโตคอลจะใช้ "กรณีงู" (request_id
),
โปรโตคอล JSON ใช้ "รูปแบบอูฐ" (requestId
) เอกสารนี้ใช้ซองอูฐ
ในตัวอย่าง JSON แต่เปลี่ยนอักขระแบบงูเมื่อพูดถึงฟิลด์โดยไม่คำนึงถึง
{
"arguments" : ["--some_argument"],
"inputs" : [
{ "path": "/path/to/my/file/1", "digest": "fdk3e2ml23d"},
{ "path": "/path/to/my/file/2", "digest": "1fwqd4qdd" }
],
"requestId" : 12
}
คุณสามารถใช้ช่อง verbosity
(ไม่บังคับ) เพื่อขอเอาต์พุตการแก้ไขข้อบกพร่องเพิ่มเติมจากเวิร์กเกอร์ได้ ขึ้นอยู่กับว่าผู้ปฏิบัติงานจะแสดงผลอะไรและอย่างไร สูงขึ้น
จะบ่งบอกถึงเอาต์พุตที่มีรายละเอียดมากขึ้น การส่ง Flag --worker_verbose
ไปยัง Bazel จะตั้งค่าช่อง verbosity
เป็น 10 แต่คุณใช้ค่าที่เล็กกว่าหรือมากกว่าได้ด้วยตัวเองสำหรับเอาต์พุตจำนวนต่างๆ
ช่อง sandbox_dir
(ไม่บังคับ) ใช้โดยผู้ปฏิบัติงานที่รองรับแซนด์บ็อกซ์แบบหลายช่องเท่านั้น
การตอบกลับงาน
WorkResponse
มีรหัสคำขอ รหัสออก 0 หรือไม่ใช่ 0 และสตริงเอาต์พุตที่อธิบายข้อผิดพลาดที่พบระหว่างการประมวลผลหรือดำเนินการตามคำขอ ช่อง output
มีคำอธิบายสั้นๆ บันทึกที่สมบูรณ์อาจ
เขียนลงใน stderr
ของพนักงาน เนื่องจากผู้ปฏิบัติงานเขียนได้แค่ WorkResponses
ไปยัง stdout
จึงเป็นเรื่องปกติที่ผู้ปฏิบัติงานจะเปลี่ยนเส้นทาง stdout
ของเครื่องมือที่ใช้ไปยัง stderr
{
"exitCode" : 1,
"output" : "Action failed with the following message:\nCould not find input
file \"/path/to/my/file/1\"",
"requestId" : 12
}
ไม่จำเป็นต้องกรอกข้อมูลครบทุกช่องตามมาตรฐานของ protobuf อย่างไรก็ตาม Bazel
WorkRequest
และ WorkResponse
ที่เกี่ยวข้องเพื่อให้มีคำขอเดียวกัน
รหัส ดังนั้นต้องระบุรหัสคำขอหากไม่เป็นศูนย์ อีเมลนี้ถูกต้อง
WorkResponse
{
"requestId" : 12,
}
request_id
จาก 0 หมายถึง "singleplex" คำขอที่ใช้เมื่อคำขอนี้
ไม่สามารถประมวลผลพร้อมกันได้กับคำขออื่นๆ เซิร์ฟเวอร์รับประกันว่าผู้ปฏิบัติงานหนึ่งๆ จะได้รับคำขอที่มี request_id
เท่ากับ 0 เท่านั้น หรือมี request_id
มากกว่า 0 เท่านั้น คำขอ Singleplex จะส่งแบบอนุกรมสำหรับ
ตัวอย่างเช่น ถ้าเซิร์ฟเวอร์ไม่ส่งคำขออีกจนกว่าจะได้รับ
การตอบกลับ (ยกเว้นคำขอยกเลิก โปรดดูด้านล่าง)
หมายเหตุ
- บัฟเฟอร์โปรโตคอลแต่ละรายการจะมีความยาวในรูปแบบ
varint
อยู่ด้านหน้า (ดูMessageLite.writeDelimitedTo()
- คำขอและการตอบกลับ JSON จะไม่มีตัวบ่งชี้ขนาดนำหน้า
- คำขอ JSON รักษาโครงสร้างเดียวกันกับ Protobuf แต่ใช้มาตรฐาน JSON และใช้ตัวอักษรประเภทอูฐสำหรับชื่อช่องทั้งหมด
- เพื่อรักษาคุณสมบัติความเข้ากันได้แบบย้อนหลังและไปข้างหน้าที่เหมือนกัน เป็น Protobuf, ผู้ปฏิบัติงาน JSON ต้องยอมรับฟิลด์ที่ไม่รู้จักในข้อความเหล่านี้ และใช้ค่าเริ่มต้นของ Protobuf สำหรับค่าที่ขาดหายไป
- Bazel จัดเก็บคำขอเป็น Protocolbufs และแปลงเป็น JSON โดยใช้ รูปแบบ JSON ของ produf
การยกเลิก
ผู้ปฏิบัติงานสามารถเลือกที่จะอนุญาตให้ยกเลิกคำของานก่อนทำเสร็จได้
ซึ่งมีประโยชน์อย่างยิ่งเมื่อเกี่ยวข้องกับการดำเนินการแบบไดนามิกที่การดําเนินการในเครื่องอาจถูกขัดจังหวะโดยการดำเนินการระยะไกลที่เร็วกว่าเป็นประจำ หากต้องการอนุญาตการยกเลิก ให้เพิ่ม supports-worker-cancellation: 1
ลงในช่อง execution-requirements
(ดูด้านล่าง) แล้วตั้งค่า Flag --experimental_worker_cancellation
คำขอยกเลิกคือ WorkRequest
ที่มีการตั้งค่าช่อง cancel
(และ
ในทำนองเดียวกัน การตอบกลับการยกเลิกคือ WorkResponse
ที่มี was_cancelled
) ช่องเดียวที่ต้องอยู่ในคำขอยกเลิกหรือยกเลิก
คำตอบคือ request_id
ซึ่งบ่งชี้ว่าคำขอใดจะยกเลิก ช่อง request_id
จะเท่ากับ 0 สําหรับผู้ทํางานแบบ Singleplex หรือ request_id
ที่ไม่ใช่ 0 ของ WorkRequest
ที่ส่งไปก่อนหน้านี้สําหรับผู้ทํางานแบบ Multiplex เซิร์ฟเวอร์อาจส่งคำขอยกเลิก
สำหรับคำขอที่ผู้ปฏิบัติงานตอบกลับแล้ว ซึ่งในกรณีนี้คือการยกเลิก
จะต้องละเว้นคำขอ
ข้อความ WorkRequest
แต่ละรายการที่ยกเลิกไม่ได้ต้องได้รับการตอบกลับเพียงครั้งเดียว ไม่ว่าจะมีการยกเลิกหรือไม่ก็ตาม เมื่อเซิร์ฟเวอร์ส่งคำขอยกเลิกแล้ว ผู้ปฏิบัติงานอาจ
ตอบกลับด้วย WorkResponse
ด้วยชุด request_id
และ was_cancelled
ที่ตั้งค่าเป็น "จริง" การส่ง WorkResponse
แบบปกติก็ใช้ได้ แต่
ระบบจะไม่สนใจช่อง output
และ exit_code
เมื่อมีการส่งการตอบกลับสำหรับ WorkRequest
ผู้ปฏิบัติงานต้องไม่แตะ
ไฟล์ในไดเรกทอรีที่ใช้งานอยู่ เซิร์ฟเวอร์จะล้างไฟล์ได้โดยไม่เสียค่าใช้จ่าย
รวมถึงไฟล์ชั่วคราว
การสร้างกฎที่ใช้แรงงาน
นอกจากนี้ คุณยังต้องสร้างกฎที่จะสร้างการดำเนินการโดยผู้ปฏิบัติงานด้วย การสร้างกฎ Starlark โดยใช้คนทำงานนั้น สร้างกฎอื่นๆ
นอกจากนี้ กฎจะต้องมีการอ้างอิงถึงตัวผู้ปฏิบัติงานเอง และ มีข้อกำหนดบางอย่างสำหรับการดำเนินการที่เกิดขึ้น
การอ้างอิงถึงผู้ปฏิบัติงาน
กฎที่ใช้ผู้ปฏิบัติงานต้องมีช่องที่อ้างถึงผู้ปฏิบัติงาน
ดังนั้นคุณจะต้องสร้างอินสแตนซ์ของกฎ \*\_binary
เพื่อกำหนด
ผู้ปฏิบัติงานของคุณ หากชื่อคนงานคือ MyWorker.Java
กฎที่เกี่ยวข้องอาจเป็นดังนี้
java_binary(
name = "worker",
srcs = ["MyWorker.Java"],
)
วิธีนี้จะสร้าง "ผู้ปฏิบัติงาน" ซึ่งอ้างถึงไบนารีของผู้ปฏิบัติงาน จากนั้น คุณจะ ตั้งกฎที่ใช้ผู้ปฏิบัติงาน กฎนี้ควรกำหนดแอตทริบิวต์ที่ หมายถึงไบนารีของผู้ปฏิบัติงาน
หากไบนารีของเวิร์กเกอร์ที่คุณสร้างอยู่ในแพ็กเกจชื่อ "work" ซึ่งอยู่ในระดับบนสุดของบิลด์ คำจำกัดความของแอตทริบิวต์อาจเป็นดังนี้
"worker": attr.label(
default = Label("//work:worker"),
executable = True,
cfg = "exec",
)
cfg = "exec"
ระบุว่าผู้ปฏิบัติงานควรสร้างขึ้นเพื่อให้ทำงานบน
แพลตฟอร์มปฏิบัติการมากกว่าแพลตฟอร์มเป้าหมาย (กล่าวคือ มีการใช้งานผู้ปฏิบัติงาน
เป็นเครื่องมือระหว่างบิลด์)
ข้อกำหนดเกี่ยวกับการทำงาน
กฎที่ใช้ผู้ปฏิบัติงานจะสร้างการทำงานเพื่อให้ผู้ปฏิบัติงานดำเนินการ เหล่านี้ จะมีข้อกำหนด 2 ข้อ
ช่อง "arguments" ซึ่งจะใช้รายการสตริงทั้งหมด ยกเว้นรายการสุดท้าย ซึ่งเป็นอาร์กิวเมนต์ที่ส่งผ่านไปยังผู้ปฏิบัติงานเมื่อเริ่มต้นระบบ องค์ประกอบสุดท้ายใน "การโต้แย้ง" เป็นอาร์กิวเมนต์
flag-file
(@-preceded) ผู้ปฏิบัติงานอ่าน อาร์กิวเมนต์จาก Flagfile ที่ระบุตามแต่ละ WorkRequest บัญชี สามารถเขียนอาร์กิวเมนต์ที่ไม่ใช่สตาร์ทอัพสำหรับผู้ปฏิบัติงานไปยังไฟล์แฟล็กนี้ได้ฟิลด์ "execution-requirements" ซึ่งใช้พจนานุกรมที่มี
"supports-workers" : "1"
,"supports-multiplex-workers" : "1"
หรือทั้ง 2 อย่างจำเป็นต้องมีฟิลด์ "arguments" และ "execution-requirements" สำหรับการดำเนินการทั้งหมดที่ส่งไปยังผู้ปฏิบัติงาน นอกจากนี้ การดําเนินการที่ควรดำเนินการโดยผู้ทํางาน JSON จะต้องมี
"requires-worker-protocol" : "json"
ในช่องข้อกําหนดการดําเนินการ"requires-worker-protocol" : "proto"
ด้วย ข้อกำหนดการดำเนินการที่ถูกต้อง แม้ว่าโปรแกรมทำงานของ Proto จะไม่จำเป็นก็ตาม เนื่องจากเป็นค่าเริ่มต้นนอกจากนี้ คุณยังตั้งค่า
worker-key-mnemonic
ในข้อกำหนดการดำเนินการได้ด้วย ช่วงเวลานี้ อาจมีประโยชน์หากคุณใช้ไฟล์ปฏิบัติการซ้ำสำหรับการดำเนินการหลายประเภท ต้องการจำแนกการทำงานของผู้ปฏิบัติงานรายนี้ไฟล์ชั่วคราวที่สร้างขึ้นในระหว่างการดำเนินการควรบันทึกไว้ในไดเรกทอรีของผู้ใช้งานที่ทำงาน ซึ่งจะเป็นการเปิดใช้แซนด์บ็อกซ์
สมมติว่าคําจํากัดความของกฎมีแอตทริบิวต์ "worker" ตามที่อธิบายไว้ข้างต้น นอกเหนือจากแอตทริบิวต์ "srcs" ที่แสดงอินพุต แอตทริบิวต์ "output" ที่แสดงเอาต์พุต และแอตทริบิวต์ "args" ที่แสดงอาร์กิวเมนต์เริ่มต้นของเวิร์กเกอร์ การเรียก ctx.actions.run
อาจมีลักษณะดังนี้
ctx.actions.run(
inputs=ctx.files.srcs,
outputs=[ctx.outputs.output],
executable=ctx.executable.worker,
mnemonic="someMnemonic",
execution_requirements={
"supports-workers" : "1",
"requires-worker-protocol" : "json"},
arguments=ctx.attr.args + ["@flagfile"]
)
ดูตัวอย่างอื่นได้ที่การใช้ PersistedWorker
ตัวอย่าง
ฐานของโค้ด Bazel ใช้ ผู้ปฏิบัติงานคอมไพเลอร์ Java นอกเหนือจาก ตัวอย่างผู้ปฏิบัติงาน JSON ที่ใช้ในการทดสอบการผสานรวม
คุณสามารถใช้สคาฟ์เฟิลดิ้งของเครื่องมือดังกล่าวเพื่อเปลี่ยนเครื่องมือที่ใช้ Java เป็นเวิร์กเกอร์ได้โดยส่งการเรียกกลับที่ถูกต้อง
ดูตัวอย่างกฎที่ใช้ผู้ปฏิบัติงานได้ที่การทดสอบการผสานรวมผู้ปฏิบัติงานของ Bazel
ผู้ร่วมให้ข้อมูลภายนอกได้ติดตั้งใช้งานผู้ปฏิบัติงานด้วยภาษาที่หลากหลาย ถ่าย ดูที่ การใช้ Polyglot ของผู้ปฏิบัติงานต่อเนื่องของ Bazel คุณสามารถดูตัวอย่างอื่นๆ อีกมากมายใน GitHub