עבודות שרשור

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

כדי ליצור שרשרת משימות, אפשר להשתמש ב-WorkManager.beginWith(OneTimeWorkRequest) או ב-WorkManager.beginWith(List<OneTimeWorkRequest>), שכל אחת מהן מחזירה מופע של WorkContinuation.

לאחר מכן אפשר להשתמש ב-WorkContinuation כדי להוסיף מכונות OneTimeWorkRequest תלויות באמצעות then(OneTimeWorkRequest) או then(List<OneTimeWorkRequest>).

כל קריאה ל-WorkContinuation.then(...) מחזירה מופע חדש של WorkContinuation. אם מוסיפים List של מכונות OneTimeWorkRequest, הבקשות האלה יכולות לפעול במקביל.

לבסוף, אפשר להשתמש ב-method‏ 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 versucht, alle Tasten aus allen Eingängen zur Ausgabe hinzuzufügen. במקרה של התנגשויות, הוא מחליף את המפתחות שהוגדרו קודם.

  • ArrayCreatingInputMerger versucht, die Eingaben zu verschmelzen und Arrays zu erstellen, wenn nötig.

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

OverwritingInputMerger

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.

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

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