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

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

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

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

बीप-ग्राफ़

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

शुरुआत में, 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"
  }
}

बीईपी में पक्ष के नतीजे

सामान्य बिल्ड, (target, configuration) पेयर से जुड़ी कार्रवाइयों का आकलन करते हैं. ज़रूरी शर्तों को पूरा करने के बाद, Bazel, (target, configuration, aspect) तीनों से जुड़े टारगेट का भी आकलन करता है. ऐसा, हर उस टारगेट के लिए किया जाता है जिस पर दिए गए किसी चालू आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) का असर पड़ा हो.

पहलू के हिसाब से इवेंट टाइप उपलब्ध न होने के बावजूद, बीईपी में पहलुओं के आकलन के नतीजे उपलब्ध होते हैं. लागू होने वाले हर (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 इवेंट से पहले दिखता है जिसमें उस इवेंट का रेफ़रंस होता है. यह "पैरंट-चाइल्ड" इवेंट के संबंध से बिलकुल उलट है, जहां पहले इवेंट को छोड़कर बाकी सभी, कम से कम एक इवेंट के एलान के बाद दिखते हैं. 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)