تسلسل الأعمال

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

لإنشاء سلسلة عمل، يمكنك استخدام WorkManager.beginWith(OneTimeWorkRequest) أو WorkManager.beginWith(List<OneTimeWorkRequest>)، حيث يعرض كل منها نسخة افتراضية من WorkContinuation.

يمكن بعد ذلك استخدام WorkContinuation لإضافة مثيلات OneTimeWorkRequest تابعة باستخدام then(OneTimeWorkRequest) أو then(List<OneTimeWorkRequest>).

يؤدي كل استدعاء للسمة WorkContinuation.then(...) إلى عرض مثيل جديد من WorkContinuation. إذا أضفت List من إجمالي OneTimeWorkRequest حالة، من المحتمل أن يتم تنفيذ هذه الطلبات بالتوازي.

أخيرًا، يمكنك استخدام الطريقة WorkContinuation.enqueue() لإضافة enqueue() إلى سلسلة WorkContinuation الخاصة بك.

لنلقِ نظرة على مثال ما. في هذا المثال، تم ضبط 3 مهام مختلفة للعاملين للتشغيل (من المحتمل أن يكون ذلك بالتوازي). بعد ذلك، يتم ضم نتائج هؤلاء العمال وتمريرها إلى وظيفة عامل تخزين مؤقت. وأخيرًا، يتم تمرير ناتج هذه المهمة إلى عامل التحميل، وهو مسؤول عن تحميل النتائج إلى خادم بعيد.

Kotlin


WorkManager.getInstance(myContext)
   // Candidates to run in parallel
   .beginWith(listOf(plantName1, plantName2, plantName3))
   // Dependent work (only runs after all previous work in chain)
   .then(cache)
   .then(upload)
   // Call enqueue to kick things off
   .enqueue()

Java


WorkManager.getInstance(myContext)
   // Candidates to run in parallel
   .beginWith(Arrays.asList(plantName1, plantName2, plantName3))
   // Dependent work (only runs after all previous work in chain)
   .then(cache)
   .then(upload)
   // Call enqueue to kick things off
   .enqueue();

عمليات دمج الإدخالات

عند سلسلة مثيلات OneTimeWorkRequest، يتم تمرير ناتج طلبات العمل الرئيسية كإدخال إلى العناصر الثانوية. لذلك في المثال أعلاه، سيتم تمرير مخرجات plantName1 وplantName2 وplantName3 كمدخلات في طلب cache.

لإدارة الإدخالات من طلبات عمل متعددة رئيسية، يستخدم WorkManager InputMerger.

يتوفّر نوعان مختلفان من InputMerger يقدّمهما WorkManager:

  • OverwritingInputMerger يحاول إضافة جميع المفاتيح من جميع الإدخالات إلى الإخراج. في حالة وجود تعارض، يستبدل المفاتيح المعدة مسبقًا.

  • يحاول ArrayCreatingInputMerger دمج الإدخالات وإنشاء الصفائف عند الضرورة.

إذا كانت لديك حالة استخدام أكثر تحديدًا، يمكنك كتابة حالة استخدام خاصة بك من خلال التصنيف الفرعي InputMerger.

استبدال إدخال البيانات

OverwritingInputMerger هي طريقة الدمج التلقائية. في حال حدوث تضاربات رئيسية في عملية الدمج، ستحلّ أحدث قيمة لمفتاح محلّ أي نُسخ سابقة في بيانات الإخراج الناتجة.

على سبيل المثال، إذا كان لكل إدخال من إدخالات النباتات مفتاح يطابق أسماء المتغيرات الخاصة به ("plantName1" و"plantName2" و"plantName3")، فعندئذٍ ستكون البيانات التي تم تمريرها إلى عامل cache ثلاثة أزواج من المفاتيح والقيم.

رسم بياني يوضح ثلاث مهام تمرر مخرجات مختلفة إلى المهمة التالية في السلسلة. نظرًا لأن النتائج الثلاثة لها مفاتيح مختلفة، تتلقى المهمة التالية ثلاثة أزواج من المفاتيح/القيمة.

إذا كان هناك تعارض، فإن العامل الأخير الذي أكمل "الفوز" ويتم تمرير قيمته إلى cache.

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

نظرًا لأن طلبات العمل الخاصة بك يتم تشغيلها بالتوازي، فليس لديك ضمانات بالترتيب الذي يتم تشغيلها به. في المثال أعلاه، يمكن أن تتضمن plantName1 قيمة إما "tulip" أو "elm"، اعتمادًا على القيمة المكتوبة في النهاية. إذا كان لديك فرصة لحدوث تعارض رئيسي وكنت بحاجة إلى الاحتفاظ بجميع بيانات الناتج في عملية دمج، قد يكون ArrayCreatingInputMerger خيارًا أفضل.

إنشاء خوارزمية دمج البيانات

في المثال أعلاه، نظرًا لأننا نريد الاحتفاظ بالناتجات الواردة من جميع العمال الذين يستخدمون أسماء المصانع، ينبغي لنا استخدام ArrayCreatingInputMerger.

Kotlin


val cache: OneTimeWorkRequest = OneTimeWorkRequestBuilder<PlantWorker>()
   .setInputMerger(ArrayCreatingInputMerger::class)
   .setConstraints(constraints)
   .build()

Java


OneTimeWorkRequest cache = new OneTimeWorkRequest.Builder(PlantWorker.class)
       .setInputMerger(ArrayCreatingInputMerger.class)
       .setConstraints(constraints)
       .build();

يعمل ArrayCreatingInputMerger على إقران كل مفتاح بمصفوفة. إذا كان كل مفتاح من المفاتيح فريدًا، فإن النتيجة تكون عبارة عن سلسلة من الصفائف المكونة من عنصر واحد.

رسم بياني يوضح ثلاث مهام تمرر مخرجات مختلفة إلى المهمة التالية في السلسلة. تم تمرير المهمة التالية ثلاث صفائف، واحدة لكل مفتاح من مفاتيح الإخراج. تحتوي كل مصفوفة على عضو واحد.

إذا كان هناك أي تعارضات رئيسية، فسيتم تجميع أي قيم مقابلة معًا في صفيف.

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

أوضاع السلاسل والعمل

يتم تنفيذ سلاسل OneTimeWorkRequest بشكل تسلسلي طالما أنّ عملها قد اكتمل بنجاح (أي تعرض Result.success()). وقد يتعذّر تنفيذ طلبات العمل أو يتم إلغاؤها أثناء التشغيل، ما قد يؤثر في ما بعد مرحلة التنفيذ في طلبات العمل التابعة.

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

مخطّط بياني يوضّح سلسلة من المهام تمت إضافة الوظيفة الأولى إلى قائمة الانتظار؛ ويتم حظر جميع المهام المتتالية حتى تنتهي المهمة الأولى.

بمجرد إدراجها في قائمة الانتظار وتلبية جميع قيود العمل، يبدأ تشغيل طلب العمل الأول. في حال اكتمال العمل بنجاح في الجذر OneTimeWorkRequest أو List<OneTimeWorkRequest> (أي عرض الرمز Result.success())، ستتم إضافة المجموعة التالية من طلبات العمل التابعة إلى قائمة الانتظار.

مخطّط بياني يوضّح سلسلة من المهام نجحت الوظيفة الأولى، وتم إدراج خلفائها المباشرين في قائمة الانتظار. يتم حظر المهام المتبقية حتى تنتهي المهام السابقة.

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

عندما يحدث خطأ أثناء معالجة أحد العاملين لطلب العمل الخاص بك، يمكنك إعادة محاولة تقديم هذا الطلب وفقًا لسياسة التراجع التي تحددها. تعني إعادة محاولة طلب يكون جزءًا من سلسلة أنه ستتم إعادة محاولة هذا الطلب فقط باستخدام بيانات الإدخال المقدمة إليه. لن يتأثر أي عمل يتم بالتوازي.

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

لمزيد من المعلومات حول تحديد استراتيجيات مخصّصة لإعادة المحاولة، يُرجى الاطّلاع على سياسة إعادة المحاولة والتراجع.

إذا كانت سياسة إعادة المحاولة غير محدّدة أو مستنفدة، أو إذا وصلت إلى حالة تُرجع فيها OneTimeWorkRequest Result.failure()، يتم وضع علامة FAILED. على طلب العمل هذا وجميع طلبات العمل التابعة

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

ينطبق المنطق نفسه عند إلغاء OneTimeWorkRequest. يتم أيضًا وضع علامة CANCELLED على أي طلبات عمل تابعة ولن يتم تنفيذ عملها.

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

يُرجى العلم أنّه في حال إلحاق المزيد من طلبات العمل بسلسلة لم تنجح أو ألغت طلبات العمل، سيتم أيضًا وضع علامة FAILED أو CANCELLED على طلب العمل الذي تم إلحاقه حديثًا، على التوالي. إذا أردت تمديد عمل سلسلة حالية، يمكنك الاطّلاع على APPEND_OR_REPLACE في ExistingWorkPolicy.

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

لمزيد من المعلومات، يُرجى الاطلاع على إلغاء العمل وإيقافه.