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

วันที่ รายงานปัญหา ดูแหล่งที่มา ตอนกลางคืน · 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 กิจกรรมในฐานะเด็ก โปรดทราบว่าเหตุการณ์ 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"
  }
}

ผลลัพธ์ Aspect ใน 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)