इस पेज पर, मल्टीप्लेक्स वर्कर के बारे में बताया गया है. साथ ही, यह भी बताया गया है कि मल्टीप्लेक्स के साथ काम करने वाले नियम कैसे लिखे जाते हैं. इसके अलावा, कुछ सीमाओं के लिए वर्कअराउंड भी दिए गए हैं.
मल्टीप्लेक्स वर्कर की मदद से, Bazel एक ही वर्कर प्रोसेस से कई अनुरोधों को हैंडल कर सकता है. मल्टी-थ्रेड वाले वर्कर के लिए, Bazel एक जैसी या बेहतर परफ़ॉर्मेंस पाने के लिए कम संसाधनों का इस्तेमाल कर सकता है. उदाहरण के लिए, हर वर्कर के लिए एक वर्कर प्रोसेस के बजाय, Bazel के पास चार मल्टीप्लेक्स वर्कर हो सकते हैं. ये सभी एक ही वर्कर प्रोसेस से बात कर सकते हैं. इसके बाद, वर्कर प्रोसेस एक साथ कई अनुरोधों को हैंडल कर सकती है. Java और Scala जैसी भाषाओं के लिए, इससे JVM वार्म-अप टाइम और JIT कंपाइलेशन टाइम बचता है. साथ ही, आम तौर पर एक ही तरह के सभी वर्कर के बीच एक शेयर किया गया कैश इस्तेमाल किया जा सकता है.
खास जानकारी
Bazel सर्वर और वर्कर प्रोसेस के बीच दो लेयर होती हैं. कुछ निमोनिक के लिए, Bazel वर्कर पूल से WorkerProxy लेता है. ये निमोनिक, प्रोसेस को एक साथ चला सकते हैं. WorkerProxy, वर्कर प्रोसेस को क्रम से अनुरोध फ़ॉरवर्ड करता है. साथ ही, request_id भी फ़ॉरवर्ड करता है. वर्कर प्रोसेस, अनुरोध को प्रोसेस करती है और WorkerMultiplexer को जवाब भेजती है. WorkerMultiplexer को जवाब मिलने पर, वह request_id को पार्स करता है. इसके बाद, जवाबों को सही WorkerProxy को वापस फ़ॉरवर्ड करता है. नॉन-मल्टीप्लेक्स वर्कर की तरह, सभी
तरह का कम्यूनिकेशन स्टैंडर्ड इन/आउट के ज़रिए किया जाता है. हालांकि, टूल, उपयोगकर्ता को दिखने वाले आउटपुट के लिए सिर्फ़
stderr का इस्तेमाल नहीं कर सकता (इसके बारे में नीचे बताया गया है).
हर वर्कर की एक कुंजी होती है. Bazel, कुंजी के हैश कोड (एनवायरमेंट वैरिएबल, एक्ज़ीक्यूशन रूट, और निमोनिक से बना) का इस्तेमाल करके यह तय करता है कि किस WorkerMultiplexer का इस्तेमाल करना है. अगर WorkerProxy के हैश कोड एक जैसे हैं, तो वे एक ही WorkerMultiplexer से कम्यूनिकेट करते हैं. इसलिए, यह मानकर कि Bazel के एक ही इनवोकेशन में एनवायरमेंट वैरिएबल और एक्ज़ीक्यूशन रूट एक जैसे हैं, हर यूनीक निमोनिक के लिए सिर्फ़ एक WorkerMultiplexer और एक वर्कर प्रोसेस हो सकती है. वर्कर की कुल संख्या अब भी --worker_max_instances से सीमित है. इसमें सामान्य वर्कर और WorkerProxy शामिल हैं.
मल्टीप्लेक्स के साथ काम करने वाले नियम लिखना
मल्टीप्लेक्स वर्कर का फ़ायदा पाने के लिए, नियम की वर्कर प्रोसेस मल्टी-थ्रेड वाली होनी चाहिए. 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, दोनों सेट हैं, तो supports-multiplex-workers को प्राथमिकता दी जाती है. --noworker_multiplex पास करके, मल्टीप्लेक्स वर्कर को ग्लोबल लेवल पर बंद किया जा सकता है.
नियमों के सेट को, अगर संभव हो, तो मल्टीप्लेक्स वर्कर का इस्तेमाल करने का सुझाव दिया जाता है. इससे मेमोरी पर पड़ने वाले दबाव को कम किया जा सकता है और परफ़ॉर्मेंस को बेहतर बनाया जा सकता है. हालांकि, फ़िलहाल मल्टीप्लेक्स वर्कर, डाइनैमिक एक्ज़ीक्यूशन के साथ काम नहीं करते. ऐसा तब तक है, जब तक वे मल्टीप्लेक्स सैंडबॉक्सिंग लागू नहीं करते. डाइनैमिक एक्ज़ीक्यूशन के साथ, बिना सैंडबॉक्स वाले मल्टीप्लेक्स वर्कर को चलाने की कोशिश करने पर, चुपचाप सैंडबॉक्स वाले सिंगलप्लेक्स वर्कर का इस्तेमाल किया जाएगा.
मल्टीप्लेक्स सैंडबॉक्सिंग
वर्कर को लागू करने के दौरान, मल्टीप्लेक्स वर्कर के लिए साफ़ तौर पर सहायता जोड़कर, उन्हें सैंडबॉक्स किया जा सकता है. सिंगलप्लेक्स वर्कर को सैंडबॉक्स करने के लिए, हर वर्कर प्रोसेस को उसके सैंडबॉक्स में चलाया जा सकता है. हालांकि, मल्टीप्लेक्स वर्कर, एक साथ किए गए कई अनुरोधों के बीच, प्रोसेस की वर्किंग डायरेक्ट्री शेयर करते हैं. मल्टीप्लेक्स वर्कर को सैंडबॉक्स करने के लिए, वर्कर को अपनी वर्किंग डायरेक्ट्री में सीधे पढ़ने और लिखने के बजाय, हर अनुरोध में तय की गई सबडायरेक्ट्री से पढ़ने और लिखने की सुविधा देनी होगी.
मल्टीप्लेक्स सैंडबॉक्सिंग के लिए, वर्कर को WorkRequest से sandbox_dir फ़ील्ड का इस्तेमाल करना होगा. साथ ही, सभी फ़ाइल को पढ़ने और लिखने के लिए, इसे प्रीफ़िक्स के तौर पर इस्तेमाल करना होगा.
बिना सैंडबॉक्स वाले अनुरोध की तुलना में, arguments और inputs फ़ील्ड में कोई बदलाव नहीं होता. हालांकि, असली इनपुट, sandbox_dir के हिसाब से होते हैं. वर्कर को, arguments और inputs में मौजूद फ़ाइल पाथ को बदलकर, इस बदले हुए पाथ से पढ़ना होगा. साथ ही, सभी आउटपुट को sandbox_dir के हिसाब से लिखना होगा.
इसमें '.' जैसे पाथ के साथ-साथ, आर्ग्युमेंट में तय की गई फ़ाइलों में मौजूद पाथ भी शामिल हैं. जैसे, "argfile" आर्ग्युमेंट.
जब कोई वर्कर, मल्टीप्लेक्स सैंडबॉक्सिंग की सुविधा देता है, तो नियमों का सेट, किसी कार्रवाई की execution_requirements में supports-multiplex-sandboxing जोड़कर, इस सुविधा के बारे में बता सकता है. इसके बाद, Bazel, मल्टीप्लेक्स सैंडबॉक्सिंग का इस्तेमाल करेगा. ऐसा तब होगा, जब --experimental_worker_multiplex_sandboxing फ़्लैग पास किया जाएगा या जब वर्कर का इस्तेमाल डाइनैमिक एक्ज़ीक्यूशन के साथ किया जाएगा.
सैंडबॉक्स वाले मल्टीप्लेक्स वर्कर की वर्कर फ़ाइलें अब भी वर्कर प्रोसेस की वर्किंग डायरेक्ट्री के हिसाब से होती हैं. इसलिए, अगर किसी फ़ाइल का इस्तेमाल वर्कर को चलाने और इनपुट के तौर पर, दोनों के लिए किया जाता है, तो उसे फ़्लैगफ़ाइल आर्ग्युमेंट में इनपुट के तौर पर और tools, executable या runfiles में भी तय करना होगा.