עבודות שרשור

באמצעות 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 (ועשויות לפעול במקביל). לאחר מכן, התוצאות של ה-Workers האלה מצורפות ומועברות למשימה של 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 versucht, die Eingaben zu verschmelzen und Arrays zu erstellen, wenn nötig.

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

מיזוג קלט החלפה

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

לדוגמה, אם לכל אחד מהקלטים של הצמח יש מפתח שמתאים לשמות המשתנים המתאימים ("plantName1",‏ "plantName2" ו-"plantName3"), הנתונים שיועברו לעובד cache יכללו שלושה זוגות של מפתח/ערך.

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

אם יש סתירה, העובד האחרון שהשלים את המשימה הוא הזוכה, והערך שלו מועבר אל cache.

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

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

ArrayCreatingInputMerger

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

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

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

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

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

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

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

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

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

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

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

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

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