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

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

मल्टीप्लेक्स वर्कर की मदद से, 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 में भी तय करना होगा.