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

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

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

एक सरल बेज़ल फ़ाइल फ़ोल्डर पर विचार करें जिसमें दो खाली शेल स्क्रिप्ट शामिल हों 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 इवेंट को चाइल्ड इवेंट के तौर पर बताता है. भले ही, 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) पेयर से जुड़ी कार्रवाइयों का मूल्यांकन किया जाता है. {0}aspect चालू होने पर, 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 इवेंट में दिए गए बार-बार होने वाले शेयर किए गए स्ट्रक्चर के बारे में बताया गया है. यह स्ट्रक्चर, स्टारलार्क डेसेट के स्ट्रक्चर से मेल खाता है.

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

namesetoffiles-bep-graph

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

NamedSetOfFiles इवेंट, हमेशा TargetComplete से जुड़े इवेंट से NamedSetOfFiles पहले, किसी 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)