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

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

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

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

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

أخيرًا، يمكنك استخدام WorkContinuation.enqueue() إلى enqueue() لسلسلة WorkContinuations.

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

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

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.

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

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