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

تتيح لك 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 مهام Worker مختلفة ليتم تنفيذها (ربما بالتوازي). يتم بعد ذلك دمج نتائج هؤلاء العاملين وتمريرها إلى مهمة عامل التخزين المؤقت. أخيرًا، يتم تمرير ناتج هذه المهمة إلى عامل تحميل (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

في المثال أعلاه، بما أنّنا نريد الاحتفاظ بالنتائج من جميع عناصر Worker التي تحمل اسم نبات، يجب استخدام 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.

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

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