बिल्ड इवेंट प्रोटोकॉल के उदाहरण

समस्या की शिकायत करें सोर्स देखें

बिल्ड इवेंट प्रोटोकॉल की पूरी जानकारी उसकी प्रोटोकॉल बफ़र परिभाषा में मिल सकती है. हालांकि, स्पेसिफ़िकेशन को देखने से पहले जानकारी हासिल करना मददगार हो सकता है.

एक ऐसे सामान्य बेज़ेल फ़ाइल फ़ोल्डर का इस्तेमाल करें जिसमें दो खाली शेल स्क्रिप्ट 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 ... को चलाते समय, जनरेट किए गए बिल्ड इवेंट का बिल्ड ग्राफ़ नीचे दिए गए ग्राफ़ की तरह दिखेगा. ऐरो से, माता-पिता और बच्चे के संबंध का पता चलता है. ध्यान रखें कि कुछ बिल्ड इवेंट और ज़्यादातर फ़ील्ड को छोटा रखने के लिए हटा दिया गया है.

बीप-ग्राफ़

पहला डायग्राम. बीईपी ग्राफ़.

शुरुआत में, एक BuildStarted इवेंट पब्लिश होता है. इवेंट से हमें पता चलता है कि बिल्ड को bazel test कमांड से शुरू किया गया है. साथ ही, यह चाइल्ड इवेंट के बारे में बताता है:

  • OptionsParsed
  • WorkspaceStatus
  • CommandLine
  • UnstructuredCommandLine
  • BuildMetadata
  • BuildFinished
  • PatternExpanded
  • Progress

पहले तीन इवेंट से यह जानकारी मिलती है कि बेज़ल को कैसे शुरू किया गया था.

PatternExpanded बिल्ड इवेंट से यह अहम जानकारी मिलती है कि ... पैटर्न को किन टारगेट तक बढ़ाया गया: //foo:foo_lib और //foo:foo_test. ऐसा करने के लिए, दो TargetConfigured इवेंट को बच्चों के तौर पर लागू करने का एलान किया जाता है. ध्यान दें कि TargetConfigured इवेंट, Configuration इवेंट को चाइल्ड इवेंट के तौर पर बताता है. भले ही, TargetConfigured इवेंट से पहले Configuration को पोस्ट किया गया हो.

माता-पिता और बच्चे के संबंध के अलावा, इवेंट अपने बिल्ड इवेंट आइडेंटिफ़ायर का इस्तेमाल करके एक-दूसरे के बारे में भी बता सकते हैं. उदाहरण के लिए, ऊपर दिए गए ग्राफ़ में, TargetComplete इवेंट अपने fileSets फ़ील्ड में NamedSetOfFiles इवेंट की जानकारी देता है.

फ़ाइल के बारे में बताने वाले इवेंट आम तौर पर, इवेंट में फ़ाइल के नाम और पाथ एम्बेड नहीं करते हैं. इसके बजाय, उनमें NamedSetOfFiles इवेंट का बिल्ड इवेंट आइडेंटिफ़ायर होता है. इसके बाद, फ़ाइल के असल नाम और पाथ शामिल हो जाएंगे. NamedSetOfFiles इवेंट की मदद से, फ़ाइलों के सेट को एक बार रिपोर्ट किया जा सकता है और कई टारगेट के लिए रेफ़र किया जा सकता है. यह स्ट्रक्चर ज़रूरी है, क्योंकि कुछ मामलों में बिल्ड इवेंट प्रोटोकॉल का आउटपुट साइज़, फ़ाइलों की संख्या के साथ चार गुना बढ़ जाएगा. ऐसा भी हो सकता है कि किसी NamedSetOfFiles इवेंट में उसकी सभी फ़ाइलें एम्बेड न हों. इसके बजाय, वे अपने बिल्ड इवेंट आइडेंटिफ़ायर की मदद से दूसरे NamedSetOfFiles इवेंट का हवाला देते हैं.

ऊपर दिए गए ग्राफ़ में, //foo:foo_lib टारगेट के लिए TargetComplete इवेंट का उदाहरण दिया गया है. इसे प्रोटोकॉल बफ़र के 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) पेयर से जुड़ी कार्रवाइयों का आकलन करते हैं. आसपेक्ट को चालू करके तैयार करते समय, Baze, (target, configuration, aspect) तीन गुना से जुड़े टारगेट का भी आकलन करता है. ऐसा हर टारगेट के लिए किया जाता है जिस पर किसी दिए गए आसपेक्ट रेशियो में असर पड़ा हो.

पहलुओं के आकलन के नतीजे, बीईपी में उपलब्ध हैं. भले ही, कोई खास इवेंट टाइप न हो. लागू होने वाले आसपेक्ट रेशियो वाले हर (target, configuration) पेयर के लिए, Baze, एक और TargetConfigured और TargetComplete इवेंट पब्लिश करता है. इस इवेंट के नतीजे के तौर पर, पहलू को टारगेट पर लागू किया जाता है. उदाहरण के लिए, अगर //:foo_lib को --aspects=aspects/myaspect.bzl%custom_aspect की मदद से बनाया गया है, तो यह इवेंट बीईपी में भी दिखेगा:

{
  "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 का इस्तेमाल कर रहा है

किसी दिए गए टारगेट (या पहलू) से बने आर्टफ़ैक्ट का पता लगाना, एक आम तौर पर बीईपी इस्तेमाल करने का एक उदाहरण है. इसे थोड़े से तैयारी के साथ सही तरीके से इस्तेमाल किया जा सकता है. इस सेक्शन में NamedSetOfFiles इवेंट के बार-बार इस्तेमाल होने वाले स्ट्रक्चर के बारे में बताया गया है. यह इवेंट स्टारलार्क Depset के स्ट्रक्चर से मेल खाता है.

NamedSetOfFiles इवेंट को प्रोसेस करते समय, उपभोक्ताओं को क्वाड्रेटिक एल्गोरिदम से बचने का ध्यान रखना चाहिए. ऐसा इसलिए, क्योंकि बड़े बिल्ड में ऐसे हज़ारों इवेंट हो सकते हैं जिनमें क्वाड्रेटिक कॉम्प्लेक्सिटी के साथ एक ट्रैवर्सल में लाखों ऑपरेशन की ज़रूरत होती है.

Namesetoffiles-bep-graph

दूसरा डायग्राम. NamedSetOfFiles बीईपी ग्राफ़.

BEP स्ट्रीम में NamedSetOfFiles इवेंट, हमेशा TargetComplete या NamedSetOfFiles इवेंट से पहले दिखता है. यह "माता-पिता और बच्चे" के बीच के संबंध से बिलकुल उलट है. यहां कम से कम एक इवेंट के एलान के बाद, पहले इवेंट को छोड़कर बाकी सभी चीज़ें दिखती हैं. 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)