إنشاء عمّال دائمين

ويمكن للموظفين الدائمين إجراء البناء بشكلٍ أسرع. إذا كانت إجراءاتك متكررة في الإصدار وكانت تكلفة بدء التشغيل مرتفعة أو ستستفيد من التخزين المؤقت المتبادل، يمكنك استخدام العامل الدائم لتنفيذ هذه الإجراءات.

يتواصل خادم Bazel مع العامل باستخدام stdin/stdout، ويتيح الوصول إلى استخدام مخازن البروتوكولات المؤقتة أو سلاسل JSON.

يتضمن تنفيذ العامل جزءين:

جعل العامل

يدعم العامل الدائم بعض المتطلبات:

  • تقرأ السياسة WorkRequests من stdin.
  • يُكتب الخيار WorkResponsesWorkResponse فقط) في stdout.
  • تقبل العلامة --persistent_worker. يجب أن يتعرّف برنامج التضمين على علامة سطر الأوامر --persistent_worker وأن يتم الاحتفاظ به بشكل مستمر فقط في حال تمرير هذه العلامة، وبخلاف ذلك، يجب تنفيذ عملية تجميع وخروج بلقطة واحدة.

وإذا كان البرنامج يستوفي هذه المتطلبات، يمكن استخدامه كعامل دائم.

طلبات العمل

يحتوي WorkRequest على قائمة بالوسيطات للعامل، وقائمة بأزواج الملخّص التي تمثّل المدخلات التي يمكن للعامل الوصول إليها (لا يتم فرض ذلك، ولكن يمكنك استخدام هذه المعلومات للتخزين المؤقت)، ومعرّف الطلب، وهو 0 للعاملين المزدوجين.

ملاحظة: على الرغم من استخدام مواصفات المخزن المؤقت للبروتوكولات &"snake case" (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 الاختياري لطلب نتائج إضافية لتصحيح الأخطاء من العامل. يعود الأمر بالكامل إلى العامل وتحديد ما يجب تنفيذه. وتشير القيم الأعلى إلى المزيد من النتائج التفصيلية. يؤدي ضبط علامة --worker_verbose على Bazel إلى ضبط الحقل 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
}

وفقًا لمعايير بروتوكول Protobuf، تكون جميع الحقول اختيارية. ومع ذلك، يتطلب Bazel WorkRequest وWorkResponse المقابل، له رقم تعريف الطلب نفسه، لذا يجب تحديد رقم تعريف الطلب إذا لم يكن صفرًا. هذا الحقل هو WorkResponse صالح.

{
  "requestId" : 12,
}

يشير request_id من 0 إلى طلب "quot;singleplex" يتم استخدامه عندما تتعذّر معالجة هذا الطلب بالتوازي مع الطلبات الأخرى. يضمن الخادم تلقّي العامل المحدّد طلبات بقيمة request_id 0 أو request_id أكبر من صفر فقط. تُرسَل طلباتِ محو البيانات المزدوجة بشكل تسلسلي، على سبيل المثال، في حال لم يُرسل الخادم طلبًا آخر إلى أن يتلقّى ردًّا (باستثناء طلبات الإلغاء، يُرجى الاطّلاع على الحالات التالية).

ملاحظات

  • يسبق كل مخزن مؤقت للبروتوكول طوله بتنسيق varint (يُرجى الاطّلاع على MessageLite.writeDelimitedTo()).
  • ولا يسبق طلب JSON واستجاباته مؤشر الحجم.
  • تدعم طلبات JSON البنية نفسها مثل البروتوكول Protobuf، ولكن استخدِم JSON العادي واستخدم حالة الجمل لجميع أسماء الحقول.
  • للحفاظ على نفس سمات التوافق بين الأمام والخلف التي يتم وضعها على بروتوكول Protobuf، على العاملين في JSON التكيف مع الحقول غير المعروفة في هذه الرسائل، واستخدام الإعدادات الأولية للقيم المفقودة
  • تخزّن Bazel الطلبات بتنسيق Protobuf وتحوّلها إلى JSON باستخدام تنسيق protobuf's JSON.

الإلغاء

ويمكن للعمّال السماح اختياريًا بإلغاء طلبات العمل قبل الانتهاء. ويُعدّ هذا مفيدًا على وجه الخصوص في ما يتعلّق بالتنفيذ الديناميكي، حيث يمكن مقاطعة التنفيذ المحلي بشكلٍ منتظم من خلال تنفيذ أسرع عن بُعد. للسماح بالإلغاء، أضِف supports-worker-cancellation: 1 إلى الحقل execution-requirements (انظر أدناه) واضبط العلامة --experimental_worker_cancellation.

طلب الإلغاء هو WorkRequest يتضمّن مجموعة الحقول cancel (وبالمثل، الاستجابة للإلغاء هي WorkResponse مع مجموعة الحقول was_cancelled). والحقل الآخر الذي يجب أن يكون مُدرَجًا في طلب الإلغاء أو الاستجابة ردّ هو request_id، للإشارة إلى الطلب المُراد إلغاؤه. وسيكون الحقل request_id عاملاً للمرّة الأولى أو السمة request_id لغير السمة WorkRequest التي تم إرسالها سابقًا للعاملين المتعددين. يمكن أن يُرسِل الخادم طلبات الإلغاء التي ردّ عليها العامل، وفي هذه الحالة يجب تجاهل طلب الإلغاء.

يجب الإجابة عن كل رسالة WorkRequest بخلاف الإلغاء مرة واحدة فقط، سواء تم إلغاؤها. بعد أن يرسل الخادم طلب إلغاء، يمكن للعامل الردّ على WorkResponse مع ضبط السمة request_id وضبط حقل was_cancelled على "صحيح". ويمكن أيضًا إرسال WorkResponse عادية، ولكن سيتم تجاهل الحقلين output وexit_code.

بعد إرسال استجابة إلى WorkRequest، يجب ألا يلمس العامل الملفات في دليل العمل. على الخادم تنظيم الملفات، بما في ذلك الملفات المؤقتة.

إنشاء القاعدة التي تستخدم العامل

وعليك أيضًا إنشاء قاعدة تُنشئ إجراءات سينفّذها العامل. ويمكنك اتّباع الخطوات التالية لإنشاء قاعدة Starlark التي تستخدم عاملاً: يمكنك إنشاء أي قاعدة أخرى.

بالإضافة إلى ذلك، يجب أن تحتوي القاعدة على مرجع للعامل نفسه، كما أن هناك بعض المتطلبات للإجراءات التي تنتجها.

الإشارة إلى العامل

يجب أن تحتوي القاعدة التي تستخدِم العامل على حقل يشير إلى العامل نفسه، لذا ستحتاج إلى إنشاء مثال لقاعدة \*\_binary لتحديد العامل لديك. إذا تم استدعاء العامل MyWorker.Java، قد تكون هذه هي القاعدة المرتبطة:

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

يؤدي هذا إلى إنشاء التصنيف "quot&quot"quot;" الذي يشير إلى البرنامج الثنائي للعامل. عليك بعد ذلك تحديد قاعدة تستخدم العامل. يجب أن تحدّد هذه القاعدة سمة تشير إلى البرنامج الثنائي للعامل.

إذا كان البرنامج الثنائي للعامل الذي أنشأته في حزمة باسم "quot;work"، والتي تقع في المستوى الأعلى من الإصدار، قد يكون ذلك تعريف السمة:

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

يشير cfg = "exec" إلى أنه يجب تصميم العامل للتشغيل على منصة التنفيذ بدلاً من النظام الأساسي المستهدف (أي أنه يتم استخدام العامل كأداة أثناء الإصدار).

متطلبات إجراء العمل

تؤدي القاعدة التي تستخدم العامل إلى إنشاء إجراءات ليتخذها العامل. هناك بعض المتطلبات لهذه الإجراءات.

  • الحقل "الوسيطات". يحتوي ذلك على قائمة بالسلاسل، وجميعها باستثناء الأخيرة وهي الوسيطات التي يتم تمريرها إلى العامل عند بدء التشغيل. يمثّل العنصر الأخير في السمة "الوسيطات"القائمة وسيطة flag-file (@-preceded). يختار الموظفون الوسيطات من ملف الإبلاغ المحدّد على أساس كل طلب عمل. يمكن للقاعدة كتابة وسيطات بدء التشغيل للعامل إلى ملف الإبلاغ هذا.

  • الحقل "execution-requirements"، الذي يحتوي على قاموس يحتوي على "supports-workers" : "1" أو "supports-multiplex-workers" : "1" أو كليهما.

    تكون حقلا "الاقتباس" و"الوسيطات&quot؛ و"&;;cutcution-requirements&quot؛ مطلوبين لكل الإجراءات التي يتم إرسالها إلى العاملين. إضافةً إلى ذلك، يجب أن تتضمّن الإجراءات التي يجب أن يتّخذها العاملون في JSON تضمين "requires-worker-protocol" : "json" في حقل متطلبات التنفيذ. ويُعدّ "requires-worker-protocol" : "proto" أيضًا متطلّبًا صالحًا للتنفيذ، على الرغم من أنّه ليس مطلوبًا للعاملين في النماذج الأولية، لأنهم التلقائيون.

    يمكنك أيضًا ضبط worker-key-mnemonic في متطلبات التنفيذ. وقد يكون هذا مفيدًا إذا كنت تعيد استخدام الملف التنفيذي لأنواع إجراءات متعددة وتريد تمييز الإجراءات من جانب هذا العامل.

  • يجب حفظ الملفات المؤقتة التي تم إنشاؤها أثناء الإجراء في دليل العامل. يؤدي هذا إلى تفعيل وضع الحماية.

بافتراض أنّ تعريف القاعدة يتضمّن السمة &&;;;; $"كما هو موضّح أعلاه، بالإضافة إلى سمة "src;srcs"، تمثّل البيانات المُدخلة، وسمة ";&hl=ar;quot; التي تمثّل المُخرجات، بالإضافة إلى سمة "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 المستخدَم في اختبارات الدمج.

يمكنك استخدام السقالة لتحويل أي أداة تستند إلى لغة Java إلى عامل عن طريق تمرير معاودة الاتصال الصحيحة.

للاطّلاع على مثال على قاعدة تستخدِم أحد العاملين، يمكنك الاطّلاع على اختبار دمج العاملين في Bazel's.

نفّذ المساهمون الخارجيون موظّفين بلغات مختلفة، ويمكنك الاطّلاع على عمليات تنفيذ Poly7ot للموظّفين الدائمين في Bazel. يمكنك العثور على المزيد من الأمثلة على GitHub.