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

किसी समस्या की शिकायत करें सोर्स देखें Nightly · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

एक आसान Bazel फ़ाइल फ़ोल्डर पर विचार करें, जिसमें दो खाली शेल स्क्रिप्ट 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

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

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

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

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

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

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

BEP में, अलग-अलग पहलुओं के लिए आकलन के नतीजे उपलब्ध होते हैं. भले ही, उनमें पहलु के हिसाब से इवेंट टाइप न हों. लागू होने वाले किसी ऐस्पेक्ट के साथ हर (target, configuration) पेयर के लिए, Bazel एक और 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 बीईपी ग्राफ़.

NamedSetOfFiles इवेंट, BEP स्ट्रीम में हमेशा उस TargetComplete या NamedSetOfFiles इवेंट से पहले दिखता है जिसका रेफ़रंस उसमें दिया गया है. यह "माता-पिता और बच्चे" के बीच के संबंध से बिलकुल उलट है. यहां कम से कम एक इवेंट के एलान के बाद, पहले इवेंट को छोड़कर बाकी सभी चीज़ें दिखती हैं. NamedSetOfFiles इवेंट की सूचना, Progress इवेंट के ज़रिए दी जाती है. इसमें कोई सेमेटिक्स नहीं होता.

ऑर्डर करने और शेयर करने से जुड़ी इन पाबंदियों को देखते हुए, किसी सामान्य उपभोक्ता को तब तक सभी NamedSetOfFiles इवेंट को बफ़र करना होगा, जब तक बीईपी स्ट्रीम खत्म नहीं हो जाती. यहां दी गई 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)