ตัวอย่างโปรโตคอลเหตุการณ์การสร้าง

รายงานปัญหา ดูแหล่งที่มา รุ่น Nightly · 7.4 7.3 · 7.2 · 7.1 · 7.0 · 6.5

ดูข้อกำหนดฉบับเต็มของ Build Event Protocol ได้ในโปรโตคอล คำจำกัดความของบัฟเฟอร์ อย่างไรก็ตาม คุณอาจต้องลองทำความเข้าใจก่อนดูข้อกำหนด

ลองใช้พื้นที่ทำงาน 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 ... ในโปรเจ็กต์นี้ กราฟบิลด์ของเหตุการณ์บิลด์ที่สร้างขึ้นจะคล้ายกับกราฟด้านล่าง ลูกศรจะแสดงถึง ความสัมพันธ์แบบพ่อแม่และลูกที่กล่าวไว้ข้างต้น โปรดทราบว่าบางเหตุการณ์ของบิลด์และ ละฟิลด์ส่วนใหญ่เพื่อความกระชับ

bep-graph

รูปที่ 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 ช่วยให้รายงานชุดไฟล์ได้เพียงครั้งเดียวและมีการอ้างอิงโดยเป้าหมายหลายรายการ โครงสร้างนี้จำเป็นเนื่องจากมิเช่นนั้น ในบางกรณี ขนาดเอาต์พุตของ Build Event Protocol จะขยายเพิ่มขึ้นตามสองเท่า จำนวนไฟล์ เหตุการณ์ 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 จะประเมินเป้าหมายที่เชื่อมโยงกับไตรเทต (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 เหตุการณ์เนื่องจากบิลด์ขนาดใหญ่อาจมีเหตุการณ์ กิจกรรมดังกล่าว ซึ่งจำเป็นต้องมีการดำเนินการนับร้อยล้านแบบในการข้ามผ่าน ความซับซ้อนของกำลังสอง

namedsetoffiles-bep-graph

รูปที่ 2 กราฟ BEP ของNamedSetOfFiles

เหตุการณ์ 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)