नियमित कर्मचारियों की मदद से आपका काम तेज़ी से हो सकता है. अगर आपने आपने अपने ऐप्लिकेशन में बार-बार कुछ ऐसा किया हो जिसकी स्टार्टअप लागत ज़्यादा हो या क्रॉस-ऐक्शन कैशिंग का फ़ायदा मिलता है, तो हो सकता है कि आपको मैन्युअल तौर पर कर्मचारी को ये कार्रवाइयां करने के लिए कहेंगे.
Basel सर्वर stdin
/stdout
का इस्तेमाल करके कर्मचारी से संपर्क करता है. यह
प्रोटोकॉल बफ़र या JSON स्ट्रिंग का इस्तेमाल करती है.
वर्कर्स को लागू करने के दो चरण होते हैं:
कर्मचारी को
लगातार काम करने वाले लोग, कुछ ज़रूरी शर्तों को पूरा करते हैं:
- यह लिखा है
WorkRequests
stdin
से. - यह लिखते हैं
WorkResponses
(और सिर्फ़
WorkResponse
s)stdout
तक. - यह
--persistent_worker
फ़्लैग स्वीकार करता है. रैपर को--persistent_worker
कमांड लाइन फ़्लैग और खुद को सिर्फ़ तभी स्थायी बनाता है, जब फ़्लैग कर दिया जाता है, नहीं तो इसे एक शॉट के ज़रिए कंपाइल करना होगा और बाहर निकलना होगा.
अगर आपका प्रोग्राम इन ज़रूरी शर्तों को पूरा करता है, तो इसका इस्तेमाल लगातार कर्मचारी!
काम के अनुरोध
WorkRequest
में, वर्कर्स के लिए आर्ग्युमेंट की सूची होती है. साथ ही, इसमें पाथ-डाइजेस्ट पेयर की सूची होती है, जो उन इनपुट को दिखाती है जिन्हें वर्कर्स ऐक्सेस कर सकते हैं. हालांकि, इसे लागू नहीं किया जाता, लेकिन कैश मेमोरी के लिए इस जानकारी का इस्तेमाल किया जा सकता है. साथ ही, इसमें अनुरोध आईडी भी होता है, जो सिंगलप्लेक्स वर्कर्स के लिए 0 होता है.
ध्यान दें: प्रोटोकॉल बफ़र में, "स्नेक केस" का इस्तेमाल किया जाता है (request_id
),
JSON प्रोटोकॉल में "कैमल केस" का इस्तेमाल किया जाता है (requestId
). इस दस्तावेज़ में ऊंट के केस का इस्तेमाल किया गया है
के उदाहरण हैं, लेकिन फ़ील्ड के बारे में बात करते समय सांप का केस
प्रोटोकॉल का इस्तेमाल करना चाहिए.
{
"arguments" : ["--some_argument"],
"inputs" : [
{ "path": "/path/to/my/file/1", "digest": "fdk3e2ml23d"},
{ "path": "/path/to/my/file/2", "digest": "1fwqd4qdd" }
],
"requestId" : 12
}
वैकल्पिक verbosity
फ़ील्ड का इस्तेमाल, डीबग करने के ज़्यादा आउटपुट का अनुरोध करने के लिए किया जा सकता है
से मिलता है. यह पूरी तरह से वर्कर पर निर्भर करता है कि आउटपुट क्या और कैसे देना है. ज़्यादा वैल्यू का मतलब है कि आउटपुट ज़्यादा शब्दों में है. Bazel को --worker_verbose
फ़्लैग पास करने पर, verbosity
फ़ील्ड को 10 पर सेट किया जाता है. हालांकि, अलग-अलग आउटपुट के लिए, छोटी या बड़ी वैल्यू का इस्तेमाल मैन्युअल तरीके से किया जा सकता है.
वैकल्पिक sandbox_dir
फ़ील्ड का इस्तेमाल सिर्फ़ वे कर्मचारी करते हैं जो सहायता करते हैं
मल्टीप्लेक्स सैंडबॉक्सिंग.
काम से जुड़े जवाब
WorkResponse
में अनुरोध आईडी, शून्य या शून्य से ज़्यादा वाला बाहर निकलने का कोड, और आउटपुट स्ट्रिंग होती है. इस स्ट्रिंग में, अनुरोध को प्रोसेस करने या उसे लागू करने में हुई गड़बड़ियों के बारे में बताया जाता है. output
फ़ील्ड में कम शब्दों में जानकारी होती है. वर्कफ़्लो के पूरे लॉग, वर्कफ़्लो के stderr
में लिखे जा सकते हैं. क्योंकि कर्मचारी सिर्फ़ जानकारी लिख सकते हैं
WorkResponses
, stdout
के लिए काम करता है. आम तौर पर, कर्मचारी stdout
को रीडायरेक्ट करता है
stderr
में इस्तेमाल किए जाने वाले किसी भी टूल की तुलना कर सकता है.
{
"exitCode" : 1,
"output" : "Action failed with the following message:\nCould not find input
file \"/path/to/my/file/1\"",
"requestId" : 12
}
प्रोटोबस के नियमों के मुताबिक, सभी फ़ील्ड भरना ज़रूरी नहीं है. हालांकि, Basel को
WorkRequest
और उससे जुड़े WorkResponse
में एक ही अनुरोध हो
id, इसलिए अगर यह शून्य नहीं है, तो अनुरोध आईडी दर्ज करना आवश्यक है. यह मान्य
WorkResponse
है.
{
"requestId" : 12,
}
0 का request_id
"सिंगलप्लेक्स" को दिखाता है अनुरोध, इस अनुरोध के समय उपयोग किया जाता है
को अन्य अनुरोधों के साथ प्रोसेस नहीं किया जा सकता. सर्वर गारंटी देता है कि
किसी दिए गए वर्कर को या तो केवल request_id
0 या केवल
request_id
, शून्य से ज़्यादा है. सिंगलप्लेक्स अनुरोध, सीरियल में भेजे जाते हैं. उदाहरण के लिए, अगर सर्वर को जवाब मिलने तक कोई दूसरा अनुरोध नहीं भेजता है (रद्द करने के अनुरोधों को छोड़कर, नीचे देखें).
ज़रूरी जानकारी
- हर प्रोटोकॉल बफ़र के आगे, उसकी लंबाई
varint
फ़ॉर्मैट में होती है (देखेंMessageLite.writeDelimitedTo()
. - JSON अनुरोधों और जवाबों के पहले, साइज़ का इंडिकेटर नहीं होता.
- JSON अनुरोध, protobuf के जैसे ही स्ट्रक्चर में होते हैं. हालांकि, इनमें स्टैंडर्ड JSON का इस्तेमाल किया जाता है. साथ ही, सभी फ़ील्ड के नामों के लिए कैमल केस का इस्तेमाल किया जाता है.
- protobuf की तरह ही, पुराने और नए वर्शन के साथ काम करने की प्रॉपर्टी बनाए रखने के लिए, JSON वर्कर्स को इन मैसेज में अनजान फ़ील्ड को स्वीकार करना होगा. साथ ही, वैल्यू मौजूद न होने पर protobuf की डिफ़ॉल्ट वैल्यू का इस्तेमाल करना होगा.
- Bazel, अनुरोधों को प्रोटोबुक के तौर पर सेव करता है और प्रोटोबुक के JSON फ़ॉर्मैट का इस्तेमाल करके उन्हें JSON में बदल देता है
रद्द किया जाना
दूसरा तरीका यह है कि वर्कर, काम खत्म होने से पहले काम के अनुरोधों को रद्द करने की अनुमति दे सकते हैं.
यह डाइनैमिक एक्ज़ीक्यूशन के मामले में खास तौर पर मददगार है, जहां लोकल
तेज़ी से रिमोट तरीके से एक्ज़ीक्यूट करने की वजह से, एक्ज़ीक्यूशन में नियमित तौर पर रुकावट आ सकती है. रद्द करने की अनुमति देने के लिए, execution-requirements
फ़ील्ड में supports-worker-cancellation: 1
जोड़ें (नीचे देखें) और --experimental_worker_cancellation
फ़्लैग सेट करें.
रद्द करने का अनुरोध, cancel
फ़ील्ड सेट वाला WorkRequest
होता है. इसी तरह, रद्द करने का जवाब, was_cancelled
फ़ील्ड सेट वाला WorkResponse
होता है. रद्द करने के अनुरोध या रद्द करने के जवाब में, request_id
फ़ील्ड होना ज़रूरी है. इससे पता चलता है कि किस अनुरोध को रद्द करना है. request_id
सिंगलप्लेक्स वर्कर के लिए फ़ील्ड 0 होगा या पिछले फ़ील्ड का नॉन-0 request_id
होगा
मल्टीप्लेक्स कर्मियों को WorkRequest
भेजा. सर्वर, उन अनुरोधों के लिए रद्द करने के अनुरोध भेज सकता है जिनका जवाब वर्कफ़्लो पहले ही दे चुका है. ऐसे में, रद्द करने के अनुरोध को अनदेखा किया जाना चाहिए.
रद्द नहीं किए गए हर WorkRequest
मैसेज का जवाब एक बार दिया जाना चाहिए. भले ही, उसे रद्द किया गया हो या नहीं. सर्वर से रद्द करने का अनुरोध मिलने के बाद, वर्कर WorkResponse
के साथ जवाब दे सकता है. इसमें request_id
सेट होगा और was_cancelled
फ़ील्ड को 'सही' पर सेट किया जाएगा. सामान्य WorkResponse
भेजने पर भी स्वीकार किया जाता है, लेकिन
output
और exit_code
फ़ील्ड को अनदेखा कर दिया जाएगा.
किसी WorkRequest
के लिए जवाब भेजने के बाद, वर्कर्स को अपनी वर्किंग डायरेक्ट्री में मौजूद फ़ाइलों में बदलाव नहीं करना चाहिए. सर्वर, फ़ाइलों को मिटा सकता है. इनमें कुछ समय के लिए सेव की गई फ़ाइलें भी शामिल हैं.
वह नियम बनाना जो वर्कर का इस्तेमाल करता है
आपको एक ऐसा नियम भी बनाना होगा जिससे वर्कफ़्लो में शामिल टास्क को पूरा करने के लिए कार्रवाइयां जनरेट हों. स्टारलार्क के लिए कर्मचारी का इस्तेमाल करने वाला नियम बनाना कोई दूसरा नियम बनाना.
इसके अलावा, नियम में वर्कफ़्लो के बारे में जानकारी होनी चाहिए. साथ ही, वर्कफ़्लो से होने वाली कार्रवाइयों के लिए कुछ ज़रूरी शर्तें भी होती हैं.
कर्मचारी को रेफ़र किया जा रहा है
वर्कफ़्लो में वर्कर्स का इस्तेमाल करने वाले नियम में, वर्कर्स का रेफ़रंस देने वाला फ़ील्ड होना चाहिए. इसलिए, आपको अपने वर्कर्स की जानकारी देने के लिए, \*\_binary
नियम का एक इंस्टेंस बनाना होगा. अगर आपके कर्मचारी का नाम MyWorker.Java
है, तो इससे जुड़ा नियम यह हो सकता है:
java_binary(
name = "worker",
srcs = ["MyWorker.Java"],
)
इससे "वर्कर" लेबल बन जाता है, जो वर्कर बाइनरी को रेफ़र करता है. इसके बाद, आपको ऐसे नियम को तय करता है जो वर्कर का इस्तेमाल करता है. इस नियम से एक ऐसा एट्रिब्यूट तय होना चाहिए जो वर्कर बाइनरी को दिखाता है.
अगर आपने जो वर्कअराउंड बाइनरी बनाई है वह "work" नाम के पैकेज में है, जो बिल्ड के सबसे ऊपरी लेवल पर है, तो एट्रिब्यूट की परिभाषा यह हो सकती है:
"worker": attr.label(
default = Label("//work:worker"),
executable = True,
cfg = "exec",
)
cfg = "exec"
बताता है कि वर्कर को आपके डिवाइस पर चलने के लिए बनाया जाना चाहिए
टारगेट प्लैटफ़ॉर्म के बजाय इस्तेमाल करने के लिए प्लैटफ़ॉर्म (यानी, वर्कर का इस्तेमाल किया जाता है)
बिल्ड के दौरान टूल के तौर पर).
काम से जुड़ी कार्रवाई की ज़रूरी शर्तें
वर्कफ़्लो में वर्कर्स का इस्तेमाल करने वाला नियम, वर्कर्स के लिए कार्रवाइयां बनाता है. ये कार्रवाइयों की कुछ ज़रूरी शर्तें होती हैं.
"तर्क" फ़ील्ड. यह स्ट्रिंग की सूची लेता है. इसमें आखिरी स्ट्रिंग को छोड़कर, सभी स्ट्रिंग, स्टार्टअप के समय वर्कर्स को भेजी जाने वाली आर्ग्युमेंट होती हैं. इसमें अंतिम तत्व "तर्क" सूची एक
flag-file
(@-पूर्वानुमान) तर्क है. कर्मचारियों ने पढ़ा तय फ़्लैगफ़ाइल से हर WorkRequest के आधार पर आर्ग्युमेंट. आपका नियम इस फ़्लैगफ़ाइल में वर्कर के लिए नॉन-स्टार्टअप तर्क लिख सकता है."execution-requirements" फ़ील्ड, जिसमें एक शब्दकोश होता है जिसमें
"supports-workers" : "1"
,"supports-multiplex-workers" : "1"
या दोनों.वर्कर्स को भेजी जाने वाली सभी कार्रवाइयों के लिए, "आर्ग्युमेंट" और "कार्रवाई करने से जुड़ी ज़रूरी शर्तें" फ़ील्ड की ज़रूरत होती है. इसके अलावा, ऐसी कार्रवाइयां जिन्हें JSON कर्मियों को
"requires-worker-protocol" : "json"
को ज़रूरी शर्तों वाला फ़ील्ड."requires-worker-protocol" : "proto"
, प्रोटो वर्कर्स के लिए ज़रूरी नहीं है, क्योंकि वे डिफ़ॉल्ट तौर पर उपलब्ध होते हैं. हालांकि, प्रोटो वर्कर्स को लागू करने के लिए,"requires-worker-protocol" : "proto"
की ज़रूरत होती है.टास्क लागू करने से जुड़ी ज़रूरी शर्तों में भी
worker-key-mnemonic
सेट किया जा सकता है. अगर एक से ज़्यादा तरह की कार्रवाइयों के लिए, एक ही एक्सीक्यूटेबल का फिर से इस्तेमाल किया जा रहा है और आपको इस वर्कर्स के हिसाब से कार्रवाइयों में अंतर करना है, तो यह तरीका कारगर हो सकता है.कार्रवाई के दौरान, जनरेट की गई अस्थायी फ़ाइलों को कर्मचारी की डायरेक्ट्री पर जाएं. इससे सैंडबॉक्सिंग की सुविधा चालू हो जाती है.
ऊपर बताए गए "worker" एट्रिब्यूट के साथ नियम की परिभाषा मानते हुए, इनपुट दिखाने वाले "srcs" एट्रिब्यूट, आउटपुट दिखाने वाले "output" एट्रिब्यूट, और वर्कर के स्टार्टअप आर्ग्युमेंट दिखाने वाले "args" एट्रिब्यूट के अलावा, ctx.actions.run
को कॉल करने का तरीका यह हो सकता है:
ctx.actions.run(
inputs=ctx.files.srcs,
outputs=[ctx.outputs.output],
executable=ctx.executable.worker,
mnemonic="someMnemonic",
execution_requirements={
"supports-workers" : "1",
"requires-worker-protocol" : "json"},
arguments=ctx.attr.args + ["@flagfile"]
)
दूसरा उदाहरण देखने के लिए, पर्सिस्टेंट वर्कर्स लागू करना देखें.
उदाहरण
Bazel कोड बेस में, Java कंपाइलर वर्कर्स के साथ-साथ, उदाहरण के तौर पर JSON वर्कर्स का भी इस्तेमाल किया जाता है. इनका इस्तेमाल, इंटिग्रेशन टेस्ट में किया जाता है.
आप इनका इस्तेमाल कर सकते हैं मैल बनाना का इस्तेमाल करें.
एक ऐसे नियम के उदाहरण के लिए जो कर्मचारी का उपयोग करता है, बेज़ल के लिए देखें वर्कर इंटिग्रेशन टेस्ट.
बाहरी योगदान देने वाले लोगों ने कई भाषाओं में वर्कर्स लागू किए हैं. Bazel के पर्सिस्टेंट वर्कर्स के लिए, कई भाषाओं में लागू किए गए तरीके देखें. GitHub पर कई और उदाहरण देखे जा सकते हैं!