অবিরাম কর্মী তৈরি করা

অবিরাম কর্মীরা আপনার বিল্ডকে দ্রুততর করতে পারে। আপনি যদি আপনার বিল্ডে বারবার অ্যাকশন করে থাকেন যেগুলির একটি উচ্চ স্টার্টআপ খরচ আছে বা ক্রস-অ্যাকশন ক্যাশিং থেকে উপকৃত হবে, তাহলে আপনি এই ক্রিয়াগুলি সম্পাদন করার জন্য আপনার নিজের অবিরাম কর্মী প্রয়োগ করতে চাইতে পারেন।

Bazel সার্ভার stdin / stdout ব্যবহার করে কর্মীর সাথে যোগাযোগ করে। এটি প্রোটোকল বাফার বা JSON স্ট্রিং ব্যবহার সমর্থন করে।

কর্মী বাস্তবায়নের দুটি অংশ রয়েছে:

কর্মী বানাচ্ছেন

একজন অবিচল কর্মী কয়েকটি প্রয়োজনীয়তা বজায় রাখে:

  • এটি তার stdin থেকে WorkRequests পড়ে।
  • এটি তার stdoutWorkResponses (এবং শুধুমাত্র WorkResponse গুলি) লিখে।
  • এটি --persistent_worker পতাকা গ্রহণ করে। র‌্যাপারকে অবশ্যই --persistent_worker কমান্ড-লাইন পতাকা চিনতে হবে এবং শুধুমাত্র সেই পতাকাটি পাস হলেই নিজেকে স্থির করে তুলতে হবে, অন্যথায় এটিকে অবশ্যই এক-শট সংকলন করতে হবে এবং প্রস্থান করতে হবে।

যদি আপনার প্রোগ্রাম এই প্রয়োজনীয়তাগুলিকে সমর্থন করে তবে এটি একটি অবিরাম কর্মী হিসাবে ব্যবহার করা যেতে পারে!

কাজের অনুরোধ

একটি WorkRequest কর্মীকে আর্গুমেন্টের একটি তালিকা, কর্মী যে ইনপুটগুলি অ্যাক্সেস করতে পারে তা প্রতিনিধিত্ব করে পাথ-ডাইজেস্ট জোড়ার একটি তালিকা (এটি প্রয়োগ করা হয় না, তবে আপনি ক্যাশে করার জন্য এই তথ্যটি ব্যবহার করতে পারেন), এবং একটি অনুরোধ আইডি, যা 0। সিঙ্গেলপ্লেক্স কর্মীদের জন্য।

দ্রষ্টব্য: যদিও প্রোটোকল বাফার স্পেসিফিকেশন "স্নেক কেস" ( request_id ) ব্যবহার করে, JSON প্রোটোকল "উট কেস" ( requestId ) ব্যবহার করে। এই দস্তাবেজটি JSON উদাহরণগুলিতে উটের কেস ব্যবহার করে, কিন্তু প্রোটোকল নির্বিশেষে ক্ষেত্রের বিষয়ে কথা বলার সময় সাপের কেস।

{
  "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 এ লেখা হতে পারে। যেহেতু কর্মীরা stdout এ শুধুমাত্র WorkResponses লিখতে পারে, শ্রমিকের পক্ষে stderr এ ব্যবহৃত যেকোনো টুলের stdout রিডাইরেক্ট করা সাধারণ।

{
  "exitCode" : 1,
  "output" : "Action failed with the following message:\nCould not find input
    file \"/path/to/my/file/1\"",
  "requestId" : 12
}

প্রোটোবাফের আদর্শ অনুসারে, সমস্ত ক্ষেত্র ঐচ্ছিক। যাইহোক, Bazel-এর জন্য WorkRequest এবং সংশ্লিষ্ট WorkResponse প্রয়োজন, একই অনুরোধ আইডি থাকতে, তাই অনুরোধ আইডিটি অশূন্য হলে অবশ্যই নির্দিষ্ট করতে হবে। এটি একটি বৈধ WorkResponse

{
  "requestId" : 12,
}

0 এর একটি request_id একটি "সিঙ্গেলপ্লেক্স" অনুরোধ নির্দেশ করে, যখন এই অনুরোধটি অন্যান্য অনুরোধের সাথে সমান্তরালভাবে প্রক্রিয়া করা যায় না তখন ব্যবহৃত হয়। সার্ভার গ্যারান্টি দেয় যে একজন প্রদত্ত কর্মী শুধুমাত্র request_id 0 বা শুধুমাত্র request_id শূন্যের চেয়ে বেশি অনুরোধ গ্রহণ করবে। সিঙ্গেলপ্লেক্স অনুরোধগুলি সিরিয়ালে পাঠানো হয়, উদাহরণস্বরূপ যদি সার্ভার একটি প্রতিক্রিয়া না পাওয়া পর্যন্ত অন্য অনুরোধ পাঠায় না (বাতিল অনুরোধগুলি ছাড়া, নীচে দেখুন)।

মন্তব্য

  • প্রতিটি প্রোটোকল বাফার এর দৈর্ঘ্যের পূর্বে varint ফরম্যাটে থাকে (দেখুন MessageLite.writeDelimitedTo()
  • JSON অনুরোধ এবং প্রতিক্রিয়া একটি আকার নির্দেশক দ্বারা পূর্বে হয় না.
  • JSON অনুরোধগুলি প্রোটোবাফের মতো একই কাঠামো বজায় রাখে, তবে স্ট্যান্ডার্ড JSON ব্যবহার করে এবং সমস্ত ক্ষেত্রের নামের জন্য উটের কেস ব্যবহার করে।
  • প্রোটোবাফের মতো একই পশ্চাদগামী এবং ফরোয়ার্ড সামঞ্জস্যপূর্ণ বৈশিষ্ট্য বজায় রাখার জন্য, JSON কর্মীদের অবশ্যই এই বার্তাগুলিতে অজানা ক্ষেত্রগুলি সহ্য করতে হবে এবং অনুপস্থিত মানগুলির জন্য প্রোটোবাফ ডিফল্টগুলি ব্যবহার করতে হবে।
  • Bazel অনুরোধগুলিকে প্রোটোবাফ হিসাবে সঞ্চয় করে এবং প্রোটোবাফের JSON ফর্ম্যাট ব্যবহার করে JSON এ রূপান্তর করে

বাতিলকরণ

কর্মীরা ঐচ্ছিকভাবে কাজের অনুরোধগুলি শেষ করার আগে বাতিল করার অনুমতি দিতে পারেন। এটি ডায়নামিক এক্সিকিউশনের ক্ষেত্রে বিশেষভাবে উপযোগী, যেখানে স্থানীয় এক্সিকিউশন নিয়মিতভাবে দ্রুত রিমোট এক্সিকিউশন দ্বারা ব্যাহত হতে পারে। বাতিলকরণের অনুমতি দিতে, execution-requirements ক্ষেত্রটিতে supports-worker-cancellation: 1 যোগ করুন (নীচে দেখুন) এবং --experimental_worker_cancellation পতাকা সেট করুন।

একটি বাতিল অনুরোধ হল cancel ক্ষেত্র সেট সহ একটি WorkRequest (এবং একইভাবে বাতিল প্রতিক্রিয়া হল was_cancelled ফিল্ড সেট সহ একটি WorkResponse )। শুধুমাত্র অন্য ক্ষেত্র যা অবশ্যই একটি বাতিল অনুরোধ বা বাতিল প্রতিক্রিয়ার মধ্যে থাকতে হবে তা হল request_id , যেটি বাতিল করতে হবে তা নির্দেশ করে। request_id ক্ষেত্রটি সিঙ্গেলপ্লেক্স কর্মীদের জন্য 0 হবে বা মাল্টিপ্লেক্স কর্মীদের জন্য পূর্বে পাঠানো request_id নন-0 WorkRequest হবে। সার্ভার সেই অনুরোধগুলির জন্য বাতিলের অনুরোধ পাঠাতে পারে যা কর্মী ইতিমধ্যেই সাড়া দিয়েছে, সেক্ষেত্রে বাতিলের অনুরোধ উপেক্ষা করতে হবে।

প্রতিটি অ-বাতিল WorkRequest বার্তার উত্তর অবশ্যই একবার দিতে হবে, তা বাতিল করা হোক বা না হোক। একবার সার্ভার একটি বাতিল অনুরোধ পাঠালে, কর্মী একটি WorkResponse এর সাথে request_id সেট এবং was_cancelled ফিল্ডটি সত্যে সেট করে সাড়া দিতে পারে। একটি নিয়মিত WorkResponse গৃহীত হয়, কিন্তু output এবং exit_code ক্ষেত্রগুলি উপেক্ষা করা হবে৷

WorkRequest জন্য একটি প্রতিক্রিয়া পাঠানো হলে, কর্মীকে অবশ্যই তার কার্যকারী ডিরেক্টরির ফাইলগুলি স্পর্শ করতে হবে না। সার্ভারটি অস্থায়ী ফাইল সহ ফাইলগুলি পরিষ্কার করতে বিনামূল্যে।

কর্মী ব্যবহার করে এমন নিয়ম তৈরি করা

আপনাকে একটি নিয়ম তৈরি করতে হবে যা কর্মীর দ্বারা সঞ্চালিত ক্রিয়াগুলি তৈরি করে। একটি স্টারলার্ক নিয়ম তৈরি করা যা একজন কর্মীকে ব্যবহার করে অন্য কোনো নিয়ম তৈরি করার মতোই।

উপরন্তু, নিয়মটিতে শ্রমিকেরই একটি রেফারেন্স থাকা দরকার এবং এটি যে ক্রিয়াগুলি তৈরি করে তার জন্য কিছু প্রয়োজনীয়তা রয়েছে।

কর্মীর কথা উল্লেখ করে

যে নিয়মটি কর্মী ব্যবহার করে তাতে এমন একটি ক্ষেত্র থাকা দরকার যা কর্মীকেই বোঝায়, তাই আপনার কর্মীকে সংজ্ঞায়িত করার জন্য আপনাকে একটি \*\_binary নিয়মের একটি উদাহরণ তৈরি করতে হবে। যদি আপনার কর্মীকে MyWorker.Java বলা হয়, তাহলে এটি সংশ্লিষ্ট নিয়ম হতে পারে:

java_binary(
    name = "worker",
    srcs = ["MyWorker.Java"],
)

এটি "কর্মী" লেবেল তৈরি করে, যা কর্মী বাইনারি বোঝায়। তারপর আপনি কর্মী ব্যবহার করে এমন একটি নিয়ম সংজ্ঞায়িত করবেন। এই নিয়মটি এমন একটি বৈশিষ্ট্যকে সংজ্ঞায়িত করা উচিত যা কর্মী বাইনারিকে বোঝায়।

আপনি যে কর্মী বাইনারি তৈরি করেছেন তা যদি "কাজ" নামে একটি প্যাকেজে থাকে, যা বিল্ডের শীর্ষ স্তরে থাকে, তাহলে এটি অ্যাট্রিবিউটের সংজ্ঞা হতে পারে:

"worker": attr.label(
    default = Label("//work:worker"),
    executable = True,
    cfg = "exec",
)

cfg = "exec" নির্দেশ করে যে কর্মীকে লক্ষ্য প্ল্যাটফর্মের পরিবর্তে আপনার কার্যকরী প্ল্যাটফর্মে চালানোর জন্য তৈরি করা উচিত (অর্থাৎ, কর্মী নির্মাণের সময় টুল হিসাবে ব্যবহৃত হয়)।

কাজের কর্মের প্রয়োজনীয়তা

যে নিয়মটি কর্মী ব্যবহার করে তা কর্মীর সঞ্চালনের জন্য ক্রিয়া তৈরি করে। এই কর্মের প্রয়োজনীয়তা একটি দম্পতি আছে.

  • "যুক্তি" ক্ষেত্র। এটি স্ট্রিংগুলির একটি তালিকা নেয়, যার মধ্যে শেষটি স্টার্টআপের পরে কর্মীকে দেওয়া আর্গুমেন্টগুলি ছাড়া বাকিগুলি। "আর্গুমেন্ট" তালিকার শেষ উপাদানটি একটি flag-file (@-পূর্ববর্তী) আর্গুমেন্ট। কর্মীরা প্রতি-ওয়ার্ক রিকোয়েস্টের ভিত্তিতে নির্দিষ্ট ফ্ল্যাগফাইল থেকে আর্গুমেন্ট পড়ে। আপনার নিয়ম এই ফ্ল্যাগফাইলে কর্মীর জন্য নন-স্টার্টআপ আর্গুমেন্ট লিখতে পারে।

  • "সম্পাদনা-প্রয়োজনীয়তা" ক্ষেত্র, যা "supports-workers" : "1" , "supports-multiplex-workers" : "1" , বা উভয় সমন্বিত একটি অভিধান নেয়।

    "আর্গুমেন্টস" এবং "এক্সিকিউশন-প্রয়োজনীয়তা" ক্ষেত্রগুলি কর্মীদের কাছে পাঠানো সমস্ত কর্মের জন্য প্রয়োজন৷ অতিরিক্তভাবে, JSON কর্মীদের দ্বারা সম্পাদিত ক্রিয়াগুলিকে "requires-worker-protocol" : "json" কার্যকর করার প্রয়োজনীয়তা ক্ষেত্রে অন্তর্ভুক্ত করতে হবে। "requires-worker-protocol" : "proto" একটি বৈধ নির্বাহের প্রয়োজনীয়তা, যদিও এটি প্রোটো কর্মীদের জন্য প্রয়োজনীয় নয়, যেহেতু তারা ডিফল্ট।

    আপনি কার্যকর করার প্রয়োজনীয়তাগুলিতে একটি worker-key-mnemonic সেট করতে পারেন। আপনি যদি একাধিক অ্যাকশন ধরনের জন্য এক্সিকিউটেবল পুনরায় ব্যবহার করছেন এবং এই কর্মী দ্বারা ক্রিয়াকলাপ আলাদা করতে চান তবে এটি কার্যকর হতে পারে।

  • ক্রিয়া চলাকালীন উত্পন্ন অস্থায়ী ফাইলগুলি কর্মীর ডিরেক্টরিতে সংরক্ষণ করা উচিত। এটি স্যান্ডবক্সিং সক্ষম করে।

উপরে বর্ণিত "কর্মী" অ্যাট্রিবিউট সহ একটি নিয়মের সংজ্ঞা অনুমান করে, ইনপুটগুলিকে প্রতিনিধিত্ব করে একটি "srcs" বৈশিষ্ট্য ছাড়াও, আউটপুটগুলিকে প্রতিনিধিত্ব করে একটি "আউটপুট" বৈশিষ্ট্য এবং কর্মী স্টার্টআপ আর্গসকে প্রতিনিধিত্ব করে একটি "আর্গস" অ্যাট্রিবিউট, ctx-এ কল 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 কোড বেস জাভা কম্পাইলার কর্মীদের ব্যবহার করে, একটি উদাহরণ ছাড়াও JSON কর্মী যা আমাদের ইন্টিগ্রেশন পরীক্ষায় ব্যবহৃত হয়।

আপনি সঠিক কলব্যাক পাস করে যেকোন জাভা-ভিত্তিক টুলকে একজন কর্মী হিসাবে তৈরি করতে তাদের ভারা ব্যবহার করতে পারেন।

একজন কর্মী ব্যবহার করে এমন একটি নিয়মের উদাহরণের জন্য, Bazel-এর কর্মী একীকরণ পরীক্ষাটি দেখুন।

বহিরাগত অবদানকারীরা বিভিন্ন ভাষায় কর্মীদের প্রয়োগ করেছে; Bazel অবিরাম কর্মীদের পলিগ্লট বাস্তবায়নের দিকে নজর দিন। আপনি GitHub এ আরও অনেক উদাহরণ খুঁজে পেতে পারেন!