قم بإنشاء تبعيات المهام لتشغيل المهام التي تعتمد على مهام أخرى

باستخدام تبعيات المهام الدفعية، يمكنك إنشاء المهام المجدولة للتنفيذ على عقد الحساب بعد إكمال مهمة رئيسية واحدة أو أكثر. على سبيل المثال، يمكنك إنشاء وظيفة تعرض كل إطار لفيلم ثلاثي الأبعاد بمهامّ منفصلة ومتوازية. تدمج المهمة النهائية الإطارات المعروضة في الفيلم الكامل فقط بعد تقديم جميع الإطارات بنجاح. بمعنى آخر، تعتمد المهمة النهائية على المهامّ الرئيسية السابقة.

تتضمن بعض السيناريوهات التي تكون فيها تبعيات المهام مفيدة ما يلي:

  • أحمال العمل بأسلوب MapReduce في السحابة.
  • الوظائف التي يمكن التعبير عن مهامّ معالجة البيانات الخاصة بها كرسم بياني غير دوري موجه (DAG).
  • عمليات العرض المسبق والعرض اللاحق، حيث يجب إكمال كل مهمة قبل أن تبدأ المهمة التالية.
  • أي وظيفة أخرى تعتمد فيها المهامّ النهائية على مخرجات المهام الأولية.

بشكل افتراضي، تتم جدولة المهامّ التابعة للتنفيذ فقط بعد اكتمال المهمة الرئيسية بنجاح. يمكنك تحديد dependency action اختياريًّا لتجاوز السلوك الافتراضي وتشغيل المهمة التابعة حتى إذا فشلت المهمة الرئيسية.

في هذه المقالة، نناقش كيفية تكوين تبعيات المهامّ باستخدام مكتبة Batch .NET. نوضح لك أولاً كيفية تمكين تبعية المهمة في وظائفك، ثم نوضح كيفية تكوين مهمة بالتبعيات. نصف أيضاً كيفية تحديد إجراء تبعية لتشغيل المهامّ التابعة إذا فشل الأصل. أخيراً، نناقش سيناريوهات التبعية التي يدعمها Batch.

تمكين تبعيات المهام

لاستخدام تبعيات المهامّ في تطبيق Batch الخاص بك، يجب عليك أولاً تكوين المهمة لاستخدام تبعيات المهامّ. في Batch .NET، قم بتمكينه على CloudJob عن طريق تعيين خاصية UsesTaskDependencies الخاصة به على true:

CloudJob unboundJob = batchClient.JobOperations.CreateJob( "job001",
    new PoolInformation { PoolId = "pool001" });

// IMPORTANT: This is REQUIRED for using task dependencies.
unboundJob.UsesTaskDependencies = true;

في مقتطف التعليمة البرمجية السابق، "batchClient" هو مثيل لفئة BatchClient.

إنشاء المهام التابعة

لإنشاء مهمة تعتمد على إكمال مهمة رئيسية واحدة أو أكثر، يمكنك تحديد أن المهمة "تعتمد على" المهام الأخرى. في Batch .NET، هيّئ الخاصية CloudTask.DependsOn بمثيل للفئة TaskDependencies:

// Task 'Flowers' depends on completion of both 'Rain' and 'Sun'
// before it is run.
new CloudTask("Flowers", "cmd.exe /c echo Flowers")
{
    DependsOn = TaskDependencies.OnIds("Rain", "Sun")
},

ينشئ مقتطف التعليمة البرمجية هذا مهمة تابعة بمعرّف المهمة "الزهور". تعتمد مهمة "الزهور" على مهمتي "المطر" و"الشمس". ستتم جدولة مهمة "Flowers" للتشغيل على عقدة حسابية فقط بعد اكتمال مهمتي "Rain" و"Sun" بنجاح.

إشعار

بشكل افتراضي، تعتبر المهمة مكتملة بنجاح عندما تكون في حالة اكتمال ورمز الخروج الخاص بها هو 0. في Batch .NET، يعني هذا أن قيمة خاصية CloudTask.State هي Completed وقيمة خاصية TaskExecutionInformation.ExitCode في CloudTask هي 0. لمعرفة كيفية تغيير ذلك، راجع قسم إجراءات التبعية.

سيناريوهات التبعية

هناك ثلاثة سيناريوهات أساسية لتبعية المهامّ يمكنك استخدامها في Azure Batch: تبعية واحد لواحد، وواحد لكثير، ونطاق معرّف المهمة. يمكن دمج هذه السيناريوهات الثلاثة لتوفير سيناريو رابع: متعدد بأطراف.

السيناريو مثال التوضيح
واحد لواحد يعتمد taskB على taskA taskA

لن تتم جدولتها للتنفيذ حتى تكتمل taskA بنجاح

رسم تخطيطي يوضح سيناريو تبعية مهمة واحد لواحد.
واحد إلى متعدد يعتمد taskC على كل من taskA و taskB

taskC لن تتم جدولتها للتنفيذ حتى يكتمل كل من taskA و taskB بنجاح

رسم تخطيطي يوضح سيناريو تبعية مهمة واحد لأكثر
نطاق معرّف المهمة يعتمد taskD على مجموعة من المهام

التي لن تتم جدولتها للتنفيذ حتى تكتمل المهام ذات المعرف من 1 إلى 10 بنجاح

رسم تخطيطي يوضح سيناريو تبعية مهمة نطاق معرّف المهمة

تلميح

يمكنك إنشاء علاقات متعدد إلى متعدد، حيث تعتمد كل من المهام ّ"ج" و"د" و"هـ" و"و" على المهام "أ" و"ب". وهذا مفيد، على سبيل المثال، في سيناريوهات المعالجة المتوازية؛ حيث تعتمد المهامّ على ناتج مهامّ المنبع المتعددة.

في الأمثلة الموجودة في هذا القسم، يتم تشغيل مهمة تابعة فقط بعد إكمال المهامّ الرئيسية بنجاح. هذا السلوك هو السلوك الافتراضي لمهمة تابعة. يمكنك تشغيل مهمة تابعة بعد فشل المهمة الرئيسية، عن طريق تحديد إجراء تبعية لتجاوز السلوك الافتراضي.

واحد إلى واحد

في علاقة رأس برأس، تعتمد المهمة على الإكمال الناجح لمهمة أحد الأبوين. لإنشاء التبعية، قم بتوفير معرف مهمة واحد للأسلوب الثابت TaskDependencies.OnId عند ملء خاصية CloudTask.DependsOn.

// Task 'taskA' doesn't depend on any other tasks
new CloudTask("taskA", "cmd.exe /c echo taskA"),

// Task 'taskB' depends on completion of task 'taskA'
new CloudTask("taskB", "cmd.exe /c echo taskB")
{
    DependsOn = TaskDependencies.OnId("taskA")
},

واحد إلى متعدد

في علاقة رأس بأطراف، تعتمد المهمة على إكمال مهامّ رئيسية متعددة. لإنشاء التبعية، قم بتوفير مجموعة من معرّفات المهامّ المحددة للأسلوب الثابت TaskDependencies.OnIds عند ملء خاصية CloudTask.DependsOn.

// 'Rain' and 'Sun' don't depend on any other tasks
new CloudTask("Rain", "cmd.exe /c echo Rain"),
new CloudTask("Sun", "cmd.exe /c echo Sun"),

// Task 'Flowers' depends on completion of both 'Rain' and 'Sun'
// before it is run.
new CloudTask("Flowers", "cmd.exe /c echo Flowers")
{
    DependsOn = TaskDependencies.OnIds("Rain", "Sun")
},

هام

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

نطاق معرف المهمة

في التبعية على نطاق من المهامّ الرئيسية، تعتمد المهمة على إكمال المهام التي تقع معرفاتها داخل النطاق الذي تحدده.

لإنشاء التبعية، قم بتوفير معرفات المهامّ الأولى والأخيرة في النطاق إلى الأسلوب الثابت TaskDependencies.OnIdRange عند ملء خاصية CloudTask.DependsOn.

هام

عند استخدام نطاقات معرّفات المهامّ للتبعيات الخاصة بك، سيتم تحديد المهام ذات المعرفات التي تمثل قيماً صحيحة بواسطة النطاق فقط. على سبيل المثال، سيحدد النطاق 1..10 المهام 3 و7، ولكن ليس 5flamingoes.

لا تعتبر الأصفار البادئة مهمة عند تقييم تبعيات النطاق، لذا فإن المهامّ ذات معرفات السلاسل 4, 04 و004 ستكون جميعها ضمن النطاق، حيث سيتم التعامل معها جميعاً على أنها مهمة 4، أول واحد يكمل سوف يرضي التبعية.

لتشغيل المهمة التابعة، يجب أن تفي كل مهمة في النطاق بالتبعية، إما بإكمالها بنجاح أو بإكمالها بفشل تم تعيينه إلى إجراء تبعية تم تعيينه بناء على إرضاءً لـ.

// Tasks 1, 2, and 3 don't depend on any other tasks. Because
// we will be using them for a task range dependency, we must
// specify string representations of integers as their ids.
new CloudTask("1", "cmd.exe /c echo 1"),
new CloudTask("2", "cmd.exe /c echo 2"),
new CloudTask("3", "cmd.exe /c echo 3"),

// Task 4 depends on a range of tasks, 1 through 3
new CloudTask("4", "cmd.exe /c echo 4")
{
    // To use a range of tasks, their ids must be integer values.
    // Note that we pass integers as parameters to TaskIdRange,
    // but their ids (above) are string representations of the ids.
    DependsOn = TaskDependencies.OnIdRange(1, 3)
},

إجراءات التبعية

افتراضيًّا، لا يتم تشغيل مهمة تابعة أو مجموعة مهامّ إلا بعد إتمام المهمة الرئيسية بنجاح. في بعض السيناريوهات، قد ترغب في تشغيل المهامّ التابعة حتى إذا فشلت المهمة الرئيسية. يمكنك تجاوز السلوك الافتراضي بتحديد إجراء تبعية يشير إلى ما إذا كانت مهمة تابعة مؤهَّلة للتشغيل.

على سبيل المثال، افترض أن مهمة تابعة تنتظر البيانات من إكمال مهمة المنبع. إذا فشلت المهمة الرئيسية، فقد تظل المهمة التابعة قادرة على التشغيل باستخدام البيانات القديمة. في هذه الحالة، يمكن أن يحدد إجراء التبعية أن المهمة التابعة مؤهّلة للتشغيل، على الرغم من فشل المهمة الرئيسية.

يعتمد إجراء التبعية على شرط الخروج للمهمة الرئيسية. يمكنك تحديد إجراء تبعية لأي من شروط الخروج التالية:

  • عند حدوث خطأ ما قبل المعالجة.
  • عند حدوث خطأ في تحميل الملف. إذا انتهت المهمة برمز خروج تم تحديده عبر exitCodes أو exitCodeRanges، ثم واجه خطأ في تحميل الملف، فإن الإجراء المحدد بواسطة كود الإنهاء يكون له الأولوية.
  • عندما تنتهي المهمة مع رمز الخروج المحدد بواسطة خاصية ExitCodes.
  • عندما تنتهي المهمة مع رمز خروج يقع ضمن النطاق المحدد بواسطة الخاصية ExitCodeRanges.
  • الحالة الافتراضية، إذا انتهت المهمة برمز خروج غير محدد بواسطة ExitCodes أو ExitCodeRanges، أو إذا انتهت المهمة مع وجود خطأ في المعالجة المسبقة وخطأ PreProcessingError لم يتم تعيين الخاصية، أو إذا فشلت المهمة بسبب خطأ في تحميل الملف ولم يتم تعيين الخاصية FileUploadError.

بالنسبة إلى .NET، يتم تعريف هذه الشروط على أنها خصائص فئة ExitConditions.

لتحديد إجراء تبعية، قم بتعيين خاصية ExitOptions.DependencyAction لشرط الخروج إلى أحد الخيارات التالية:

  • إرضاء: يشير إلى أن المهامّ التابعة مؤهلة للتشغيل إذا انتهت المهمة الرئيسية مع ظهور خطأ محدد.
  • حظر: يشير إلى أن المهامّ التابعة غير مؤهلة للتشغيل.

الإعداد الافتراضي لخاصية DependencyAction هو Satisfy لكود الخروج 0، وBlock لجميع شروط الخروج الأخرى.

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

// Task A is the parent task.
new CloudTask("A", "cmd.exe /c echo A")
{
    // Specify exit conditions for task A and their dependency actions.
    ExitConditions = new ExitConditions
    {
        // If task A exits with a pre-processing error, block any downstream tasks (in this example, task B).
        PreProcessingError = new ExitOptions
        {
            DependencyAction = DependencyAction.Block
        },
        // If task A exits with the specified error codes, block any downstream tasks (in this example, task B).
        ExitCodes = new List<ExitCodeMapping>
        {
            new ExitCodeMapping(10, new ExitOptions() { DependencyAction = DependencyAction.Block }),
            new ExitCodeMapping(20, new ExitOptions() { DependencyAction = DependencyAction.Block })
        },
        // If task A succeeds or fails with any other error, any downstream tasks become eligible to run 
        // (in this example, task B).
        Default = new ExitOptions
        {
            DependencyAction = DependencyAction.Satisfy
        }
    }
},
// Task B depends on task A. Whether it becomes eligible to run depends on how task A exits.
new CloudTask("B", "cmd.exe /c echo B")
{
    DependsOn = TaskDependencies.OnId("A")
},

Code sample

يوضح نموذج مشروع TaskDependencies على GitHub:

  • كيفية تمكين الاعتماد على المهمة في الوظيفة.
  • كيفية إنشاء المهامّ التي تعتمد على مهامّ أخرى.
  • كيفية تنفيذ هذه المهامّ على مجموعة من عقد الحوسبة.

الخطوات التالية