ดูข้อมูลจำเพาะทั้งหมดของโปรโตคอลเหตุการณ์บิลด์ได้ในคำจำกัดความบัฟเฟอร์ของโปรโตคอล แต่การเสริมสร้างสัญชาตญาณ ก่อนดูข้อกำหนดอาจช่วยได้
ลองพิจารณาพื้นที่ทำงานของ Bazel แบบง่ายที่ประกอบด้วยสคริปต์ Shell เปล่า 2 สคริปต์ ได้แก่ foo.sh
และ foo_test.sh
และไฟล์ BUILD
ต่อไปนี้
sh_library(
name = "foo_lib",
srcs = ["foo.sh"],
)
sh_test(
name = "foo_test",
srcs = ["foo_test.sh"],
deps = [":foo_lib"],
)
เมื่อเรียกใช้ bazel test ...
ในโปรเจ็กต์นี้ กราฟบิลด์ของเหตุการณ์บิลด์ที่สร้างขึ้นจะคล้ายกับกราฟด้านล่าง ลูกศรแสดงถึงความสัมพันธ์
ระหว่างพ่อแม่กับลูกที่ได้กล่าวไปแล้ว โปรดทราบว่าเหตุการณ์การสร้างบางรายการและช่องส่วนใหญ่
ได้รับการละเว้นเพื่อความสั้นกระชับ
รูปที่ 1 กราฟ BEP
เมื่อเริ่มต้น ระบบจะเผยแพร่เหตุการณ์ BuildStarted
เหตุการณ์แจ้งให้เราทราบว่ามีการเรียกใช้บิลด์ผ่านคําสั่ง bazel test
และประกาศเหตุการณ์ย่อย
OptionsParsed
WorkspaceStatus
CommandLine
UnstructuredCommandLine
BuildMetadata
BuildFinished
PatternExpanded
Progress
3 เหตุการณ์แรกให้ข้อมูลเกี่ยวกับวิธีการเรียก Bazel
เหตุการณ์บิลด์ PatternExpanded
ให้ข้อมูลเชิงลึกเกี่ยวกับเป้าหมายที่เฉพาะเจาะจงซึ่งรูปแบบ ...
ขยายไปยัง //foo:foo_lib
และ //foo:foo_test
โดยจะประกาศ TargetConfigured
เหตุการณ์ 2 รายการเป็นเหตุการณ์ย่อย โปรดทราบว่าเหตุการณ์ TargetConfigured
จะประกาศกิจกรรม Configuration
เป็นกิจกรรมย่อย แม้ว่า Configuration
จะโพสต์ก่อนกิจกรรม TargetConfigured
ก็ตาม
นอกจากความสัมพันธ์แบบระดับบนสุดและย่อยแล้ว เหตุการณ์ยังอาจเชื่อมโยงถึงกันโดยใช้ตัวระบุเหตุการณ์บิลด์ เช่น ในกราฟด้านบน เหตุการณ์ TargetComplete
จะหมายถึงเหตุการณ์ NamedSetOfFiles
ในช่อง fileSets
โดยปกติแล้ว การสร้างเหตุการณ์ที่อ้างอิงไฟล์มักไม่ฝังชื่อไฟล์และเส้นทางในเหตุการณ์ แต่จะมีตัวระบุเหตุการณ์บิลด์ของเหตุการณ์ NamedSetOfFiles
ซึ่งจะมีชื่อไฟล์และเส้นทางจริงรวมอยู่ด้วย เหตุการณ์ NamedSetOfFiles
ช่วยให้รายงานชุดไฟล์ได้เพียงครั้งเดียวและอ้างถึงโดยหลายเป้าหมาย โครงสร้างนี้เป็นสิ่งที่จำเป็นเนื่องจากในบางกรณี ขนาดเอาต์พุตของโปรโตคอลเหตุการณ์บิลด์จะขยายเพิ่มขึ้นเป็นเท่าตัวเมื่อมีจำนวนไฟล์เพิ่มขึ้น นอกจากนี้เหตุการณ์ NamedSetOfFiles
อาจไม่ได้ฝังไฟล์ทั้งหมด แต่ให้อ้างอิงเหตุการณ์ NamedSetOfFiles
อื่นๆ ผ่านตัวระบุเหตุการณ์การสร้างแทน
ด้านล่างนี้เป็นอินสแตนซ์ของเหตุการณ์ TargetComplete
สำหรับเป้าหมาย //foo:foo_lib
จากกราฟด้านบนซึ่งพิมพ์ออกมาในการนำเสนอ JSON ของบัฟเฟอร์โปรโตคอล
ตัวระบุเหตุการณ์ของบิลด์มีเป้าหมายเป็นสตริงทึบและอ้างถึงเหตุการณ์ Configuration
โดยใช้ตัวระบุเหตุการณ์บิลด์ เหตุการณ์นี้จะไม่ประกาศ
กิจกรรมย่อยใดๆ เพย์โหลดประกอบด้วยข้อมูลเกี่ยวกับว่าสร้างเป้าหมายสำเร็จหรือไม่ ชุดไฟล์เอาต์พุต และประเภทเป้าหมายที่สร้าง
{
"id": {
"targetCompleted": {
"label": "//foo:foo_lib",
"configuration": {
"id": "544e39a7f0abdb3efdd29d675a48bc6a"
}
}
},
"completed": {
"success": true,
"outputGroup": [{
"name": "default",
"fileSets": [{
"id": "0"
}]
}],
"targetKind": "sh_library rule"
}
}
ผลลัพธ์ใน BEP
บิลด์ทั่วไปจะประเมินการดำเนินการที่เชื่อมโยงกับคู่ (target, configuration)
เมื่อสร้างด้วยมุมมอง Bazel จะประเมินเป้าหมายที่เชื่อมโยงกับ 3 องค์ประกอบเพิ่มขึ้น (target, configuration,
aspect)
สำหรับแต่ละเป้าหมายที่ได้รับผลกระทบจากลักษณะที่เปิดใช้หนึ่งๆ
ผลการประเมินในด้านต่างๆ จะแสดงอยู่ใน BEP แม้ว่าจะไม่มีประเภทเหตุการณ์ที่เฉพาะเจาะจงในด้านต่างๆ สำหรับ (target, configuration)
แต่ละคู่ที่มีแง่มุมที่เกี่ยวข้อง Bazel จะเผยแพร่เหตุการณ์ TargetConfigured
และ TargetComplete
เพิ่มเติม ซึ่งเป็นผลมาจากการนำแง่มุมไปใช้กับเป้าหมาย ตัวอย่างเช่น หาก //:foo_lib
สร้างด้วย --aspects=aspects/myaspect.bzl%custom_aspect
กิจกรรมนี้จะปรากฏใน BEP ด้วย
{
"id": {
"targetCompleted": {
"label": "//foo:foo_lib",
"configuration": {
"id": "544e39a7f0abdb3efdd29d675a48bc6a"
},
"aspect": "aspects/myaspect.bzl%custom_aspect"
}
},
"completed": {
"success": true,
"outputGroup": [{
"name": "default",
"fileSets": [{
"id": "1"
}]
}]
}
}
กำลังบริโภค NamedSetOfFiles
การพิจารณาสิ่งประดิษฐ์ที่สร้างขึ้นตามเป้าหมาย (หรือแง่มุมหนึ่ง) เป็นกรณีการใช้งานทั่วไปของ BEP ซึ่งสามารถดำเนินการได้อย่างมีประสิทธิภาพโดยจะมีการเตรียมความพร้อมในระดับหนึ่ง ส่วนนี้จะพูดถึงโครงสร้างที่ใช้ร่วมกันซ้ำๆ ที่กิจกรรม NamedSetOfFiles
นำเสนอ ซึ่งตรงกับโครงสร้างของ Depset Starlark
ผู้บริโภคต้องระมัดระวังหลีกเลี่ยงอัลกอริทึมกำลังสองเมื่อประมวลผลเหตุการณ์ NamedSetOfFiles
เนื่องจากบิลด์ขนาดใหญ่อาจมีเหตุการณ์ดังกล่าวหลายหมื่นเหตุการณ์ ซึ่งต้องใช้การดำเนินการนับร้อยล้านครั้งในกระบวนการส่งผ่านที่มีความซับซ้อนแบบกำลังสอง
รูปที่ 2 NamedSetOfFiles
กราฟ BEP
เหตุการณ์ NamedSetOfFiles
จะปรากฏในสตรีม BEP เสมอก่อนเหตุการณ์ TargetComplete
หรือ NamedSetOfFiles
ที่อ้างอิงเหตุการณ์ดังกล่าว ค่านี้จะผกผันกับความสัมพันธ์ของเหตุการณ์ "หลัก-ย่อย" ซึ่งทั้งหมดยกเว้นเหตุการณ์แรกปรากฏขึ้นหลังจากประกาศเหตุการณ์อย่างน้อย 1 เหตุการณ์ เหตุการณ์ NamedSetOfFiles
มีการประกาศโดยเหตุการณ์ Progress
โดยไม่มีความหมาย
ด้วยข้อจำกัดในการจัดลำดับและการแชร์เหล่านี้ ผู้บริโภคทั่วไปจึงต้องบัฟเฟอร์เหตุการณ์ NamedSetOfFiles
ทั้งหมดจนกว่าสตรีม BEP จะหมดลง สตรีมเหตุการณ์ JSON และโค้ด Python ต่อไปนี้สาธิตวิธีสร้างแผนที่จากเป้าหมาย/มุมมองไปยังอาร์ติแฟกต์ที่สร้างขึ้นในกลุ่มเอาต์พุต "เริ่มต้น" และวิธีประมวลผลเอาต์พุตสำหรับชุดย่อยของเป้าหมาย/มุมมองที่สร้างขึ้น
named_sets = {} # type: dict[str, NamedSetOfFiles]
outputs = {} # type: dict[str, dict[str, set[str]]]
for event in stream:
kind = event.id.WhichOneof("id")
if kind == "named_set":
named_sets[event.id.named_set.id] = event.named_set_of_files
elif kind == "target_completed":
tc = event.id.target_completed
target_id = (tc.label, tc.configuration.id, tc.aspect)
outputs[target_id] = {}
for group in event.completed.output_group:
outputs[target_id][group.name] = {fs.id for fs in group.file_sets}
for result_id in relevant_subset(outputs.keys()):
visit = outputs[result_id].get("default", [])
seen_sets = set(visit)
while visit:
set_name = visit.pop()
s = named_sets[set_name]
for f in s.files:
process_file(result_id, f)
for fs in s.file_sets:
if fs.id not in seen_sets:
visit.add(fs.id)
seen_sets.add(fs.id)