मल्टीप्लेक्स वर्कर (एक्सपेरिमेंटल फ़ीचर)

इस पेज पर, मल्टीप्लेक्स वर्कर के बारे में बताया गया है. साथ ही, मल्टीप्लेक्स के साथ काम करने वाले नियम लिखने का तरीका और कुछ सीमाओं को हल करने के तरीके बताए गए हैं.

मल्टीप्लेक्स वर्कर की मदद से, Bazel एक ही वर्कर प्रोसेस से कई अनुरोधों को मैनेज कर सकता है. मल्टी-थ्रेड वर्कर के लिए, Bazel कम रिसॉर्स का इस्तेमाल करके, उसी या बेहतर परफ़ॉर्मेंस को हासिल कर सकता है. उदाहरण के लिए, हर वर्कर के लिए एक वर्कर प्रोसेस होने के बजाय, Bazel के पास एक ही वर्कर प्रोसेस से कम्यूनिकेट करने वाले चार मल्टीप्लेक्स वर्कर हो सकते हैं. इससे अनुरोधों को एक साथ हैंडल किया जा सकता है. Java और Scala जैसी भाषाओं के लिए, इससे JVM को चालू होने में लगने वाला समय और JIT कंपाइलेशन में लगने वाला समय बचता है. साथ ही, इससे एक ही तरह के सभी वर्कर के बीच एक शेयर की गई कैश मेमोरी का इस्तेमाल किया जा सकता है.

खास जानकारी

Bazel सर्वर और वर्कर प्रोसेस के बीच दो लेयर होती हैं. कुछ नेमोनिक के लिए, Bazel वर्कर पूल से WorkerProxy लेता है. ये नेमोनिक, प्रोसेस को एक साथ चला सकते हैं. WorkerProxy, अनुरोधों को वर्कर प्रोसेस को क्रम से भेजता है. साथ ही, request_id भी भेजता है. वर्कर प्रोसेस, अनुरोध को प्रोसेस करता है और WorkerMultiplexer को जवाब भेजता है. जब WorkerMultiplexer को कोई जवाब मिलता है, तो वह request_id को पार्स करता है. इसके बाद, जवाबों को सही WorkerProxy पर वापस भेज देता है. नॉन-मल्टीप्लेक्स वर्कर की तरह ही, सभी कम्यूनिकेशन स्टैंडर्ड इन/आउट के ज़रिए किए जाते हैं. हालांकि, टूल सिर्फ़ stderr का इस्तेमाल, उपयोगकर्ता को दिखने वाले आउटपुट के लिए नहीं कर सकता (नीचे देखें).

हर वर्कर के पास एक कुंजी होती है. Bazel, कुंजी के हैश कोड का इस्तेमाल करता है. यह कोड, एनवायरमेंट वैरिएबल, एक्ज़ीक्यूशन रूट, और नेमोनिक से मिलकर बना होता है. इससे यह तय किया जाता है कि किस WorkerMultiplexer का इस्तेमाल करना है. अगर WorkerProxys का हैश कोड एक जैसा है, तो वे एक ही WorkerMultiplexer से कम्यूनिकेट करते हैं. इसलिए, अगर Bazel के एक इनवोकेशन में एनवायरमेंट वैरिएबल और एक्ज़ीक्यूशन रूट एक ही हैं, तो हर यूनीक नेमोनिक के लिए सिर्फ़ एक WorkerMultiplexer और एक वर्कर प्रोसेस हो सकती है. नियमित कर्मचारियों और WorkerProxy को मिलाकर, कर्मचारियों की कुल संख्या अब भी --worker_max_instances से ज़्यादा नहीं हो सकती.

मल्टीप्लेक्स के साथ काम करने वाले नियम लिखना

मल्टीप्लेक्स वर्कर का फ़ायदा पाने के लिए, नियम की वर्कर प्रोसेस मल्टी-थ्रेड होनी चाहिए. Protobuf, नियमों के सेट को एक ही अनुरोध को पार्स करने की अनुमति देता है. भले ही, स्ट्रीम में कई अनुरोध मौजूद हों. जब भी वर्कर प्रोसेस, स्ट्रीम से मिले किसी अनुरोध को पार्स करती है, तो उसे अनुरोध को नए थ्रेड में हैंडल करना चाहिए. अलग-अलग थ्रेड एक ही समय पर स्ट्रीम में डेटा लिख सकते हैं. इसलिए, वर्कर प्रोसेस को यह पक्का करना होगा कि जवाब एटॉमिक तरीके से लिखे गए हों. इसका मतलब है कि मैसेज ओवरलैप न हों. जवाबों में, उस अनुरोध का request_id शामिल होना चाहिए जिसे वे हैंडल कर रहे हैं.

मल्टीप्लेक्स आउटपुट को हैंडल करना

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

मल्टीप्लेक्स में काम करने वाले लोगों के लिए सुविधा चालू करना

मल्टीप्लेक्स वर्कर की सुविधा, डिफ़ॉल्ट रूप से चालू नहीं होती. नियमों के सेट में, मल्टीप्लेक्स वर्कर चालू किए जा सकते हैं. इसके लिए, कार्रवाई के execution_requirements में supports-multiplex-workers टैग का इस्तेमाल किया जाता है. यह ठीक उसी तरह से काम करता है जैसे supports-workers टैग, रेगुलर वर्कर को चालू करता है. रेगुलर वर्कर का इस्तेमाल करते समय, वर्कर की रणनीति तय करनी होती है. इसे नियमों के सेट के लेवल पर (उदाहरण के लिए, --strategy=[some_mnemonic]=worker) या रणनीति के लेवल पर (उदाहरण के लिए, --dynamic_local_strategy=worker,standalone) तय किया जा सकता है. इसके लिए, किसी अन्य फ़्लैग की ज़रूरत नहीं होती. साथ ही, अगर दोनों फ़्लैग सेट किए गए हैं, तो supports-multiplex-workers को supports-workers से ज़्यादा प्राथमिकता दी जाती है. --noworker_multiplex पास करके, मल्टीप्लेक्स वर्कर को ग्लोबल लेवल पर बंद किया जा सकता है.

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

मल्टीप्लेक्स सैंडबॉक्सिंग

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

मल्टीप्लेक्स सैंडबॉक्सिंग के लिए, वर्कर को WorkRequest से sandbox_dir फ़ील्ड का इस्तेमाल करना होगा. साथ ही, सभी फ़ाइल रीड और राइट के लिए, इसे प्रीफ़िक्स के तौर पर इस्तेमाल करना होगा. सैंडबॉक्स से बाहर किए गए अनुरोध में arguments और inputs फ़ील्ड में कोई बदलाव नहीं होता. हालांकि, असल इनपुट sandbox_dir के हिसाब से होते हैं. वर्कर को arguments और inputs में मिले फ़ाइल पाथ का अनुवाद करना होगा, ताकि इस बदले हुए पाथ से पढ़ा जा सके. साथ ही, उसे सभी आउटपुट को sandbox_dir के हिसाब से लिखना होगा. इसमें '.' जैसे पाथ के साथ-साथ, आर्ग्युमेंट में बताई गई फ़ाइलों (जैसे कि "argfile" आर्ग्युमेंट) में मिले पाथ भी शामिल होते हैं.

जब कोई वर्कर मल्टीप्लेक्स सैंडबॉक्सिंग के साथ काम करता है, तो ruleset इस सुविधा के बारे में बता सकता है. इसके लिए, उसे किसी कार्रवाई के execution_requirements में supports-multiplex-sandboxing जोड़ना होगा. इसके बाद, अगर --experimental_worker_multiplex_sandboxing फ़्लैग पास किया जाता है या वर्कर का इस्तेमाल डाइनैमिक एक्ज़ीक्यूशन के साथ किया जाता है, तो Bazel मल्टीप्लेक्स सैंडबॉक्सिंग का इस्तेमाल करेगा.

सैंडबॉक्स किए गए मल्टीप्लेक्स वर्कर की वर्कर फ़ाइलें, अब भी वर्कर प्रोसेस की वर्किंग डायरेक्ट्री से जुड़ी होती हैं. इसलिए, अगर किसी फ़ाइल का इस्तेमाल वर्कर को चलाने और इनपुट के तौर पर किया जाता है, तो उसे flagfile आर्ग्युमेंट में इनपुट के तौर पर और tools, executable या runfiles में भी शामिल करना होगा.