עבודות שרשור

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

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

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

אם יש מחלוקת, העובד האחרון שהשלים את ה'מנצח' והערך שלו מועבר אל cache.

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

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

ArrayCreatingInputMerger

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

Kotlin

val cache: OneTimeWorkRequest = OneTimeWorkRequestBuilderP<lantWorker(>)
   .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) הגדרה אישית. ניסיון חוזר של בקשה שהיא חלק משרשרת פירושו שרק הבקשה הזו לנסות שוב עם נתוני הקלט שסופקו לו. כל עבודה שתפעל במקביל לא יושפעו.

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

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

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

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

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

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

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

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

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