עבודות שרשור

‫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

בדוגמה שלמעלה, אם רוצים לשמור את הפלט מכל ה-Workers של שמות הצמחים, צריך להשתמש ב-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 מתווספת לתור בשרשרת של בקשות עבודה, כל בקשות העבודה הבאות נחסמות עד שהעבודה של בקשת העבודה הראשונה מסתיימת.

דיאגרמה שמציגה שרשרת של משימות. המשימה הראשונה מתווספת לתור, וכל המשימות הבאות נחסמות עד שהמשימה הראשונה מסתיימת.

אחרי שהבקשה מתווספת לתור וכל אילוצי העבודה מתקיימים, בקשת העבודה הראשונה מתחילה לפעול. אם העבודה הושלמה בהצלחה ב-root OneTimeWorkRequest או List<OneTimeWorkRequest> (כלומר, היא מחזירה Result.success()), אז הבקשות הבאות של עבודה תלויה יתווספו לתור.

דיאגרמה שמציגה שרשרת של משימות. העבודה הראשונה הסתיימה בהצלחה, ושתי העבודות הבאות בתור הוכנסו לתור. המשרות שנותרו חסומות עד שהמשרות הקודמות להן מסתיימות.

כל עוד כל בקשה לעבודה מסתיימת בהצלחה, אותו דפוס מועבר דרך שאר הבקשות בשרשרת עד שכל העבודה בשרשרת מסתיימת. זהו המקרה הפשוט והמועדף, אבל חשוב לא פחות לטפל במצבי שגיאה.

אם מתרחשת שגיאה בזמן שעובד מעבד את בקשת העבודה שלכם, אתם יכולים לנסות שוב את הבקשה בהתאם למדיניות ההשהיה לפני ניסיון חוזר (backoff) שהגדרתם. ניסיון חוזר לשלוח בקשה שהיא חלק משרשרת אומר שרק הבקשה הזו תישלח מחדש עם נתוני הקלט שסופקו לה. העבודה שמתבצעת במקביל לא תיפגע.

דיאגרמה שמציגה שרשרת של משימות. אחת מהמשימות נכשלה, אבל הוגדרה לה מדיניות השהיה לפני ניסיון חוזר. המשימה הזו תופעל מחדש אחרי שיעבור פרק הזמן המתאים. העבודות שאחריה בשרשרת נחסמות עד שהיא פועלת בהצלחה.

מידע נוסף על הגדרת אסטרטגיות מותאמות אישית לניסיון חוזר זמין במאמר מדיניות בנושא ניסיון חוזר והשהיה.

אם מדיניות הניסיון החוזר לא מוגדרת או שהניסיונות החוזרים מוצו, או אם מגיעים למצב שבו OneTimeWorkRequest מחזירה Result.failure(), בקשת העבודה הזו וכל בקשות העבודה שתלויות בה מסומנות כFAILED.

דיאגרמה שמציגה שרשרת של משימות. עבודה אחת נכשלה ואי אפשר לנסות שוב. כתוצאה מכך, גם כל העבודות שאחריה בשרשרת נכשלות.

אותה לוגיקה חלה גם כשמבטלים OneTimeWorkRequest. גם בקשות עבודה תלויות מסומנות בסימן CANCELLED והעבודה שלהן לא תבוצע.

דיאגרמה שמציגה שרשרת של משימות. משימה אחת בוטלה. כתוצאה מכך, גם כל העבודות שבאות אחריה בשרשרת מבוטלות.

חשוב לדעת שאם תוסיפו בקשות עבודה נוספות לשרשרת שבה בקשות העבודה נכשלו או בוטלו, גם בקשת העבודה החדשה שתוסיפו תסומן בסימן FAILED או CANCELLED, בהתאמה. אם רוצים להרחיב את העבודה של שרשרת קיימת, אפשר לעיין בAPPEND_OR_REPLACE ב-ExistingWorkPolicy.

כשיוצרים שרשרות של בקשות עבודה, בקשות עבודה תלויות צריכות להגדיר מדיניות ניסיון חוזר כדי להבטיח שהעבודה תמיד תושלם בזמן. בקשות עבודה שנכשלו עלולות לגרום לשרשרות לא שלמות או למצב לא צפוי.

מידע נוסף זמין במאמר ביטול והפסקה של עבודה.