งานเชน

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 ที่แคชไว้ สุดท้าย ผลลัพธ์ของงานนั้นจะส่งไปยัง 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 เพื่อจัดการอินพุตจากคำของานหลักหลายรายการ

WorkManager มี InputMerger 2 ประเภทที่แตกต่างกัน ได้แก่

  • OverwritingInputMerger พยายามเพิ่มคีย์ทั้งหมดจากอินพุตทั้งหมดไปยังเอาต์พุต ในกรณีที่เกิดความขัดแย้ง ระบบจะเขียนทับคีย์ที่ตั้งค่าไว้ก่อนหน้านี้

  • ArrayCreatingInputMerger พยายามผสานอินพุต โดยสร้างอาร์เรย์เมื่อจำเป็น

หากมี Use Case ที่เฉพาะเจาะจงมากขึ้น คุณสามารถเขียนของคุณเองได้โดยใช้คลาสย่อย InputMerger

OverwritingInputMerger

OverwritingInputMerger เป็นวิธีการรวมเริ่มต้น หากมีคีย์ที่ขัดแย้งกันในการผสาน ค่าล่าสุดของคีย์จะเขียนทับเวอร์ชันก่อนหน้าในข้อมูลเอาต์พุตที่ได้

เช่น หากอินพุตของโรงงานแต่ละรายการมีคีย์ที่ตรงกับชื่อตัวแปรที่เกี่ยวข้อง ("plantName1", "plantName2" และ "plantName3") ข้อมูลที่ส่งไปยัง Worker cache จะมีคู่คีย์-ค่า 3 คู่

แผนภาพแสดงงาน 3 งานที่ส่งเอาต์พุตที่แตกต่างกันไปยังงานถัดไปในเชน เนื่องจากเอาต์พุตทั้ง 3 รายการมีคีย์ที่แตกต่างกัน งานถัดไปจึงได้รับคู่คีย์/ค่า 3 คู่

หากเกิดความขัดแย้ง ผู้ปฏิบัติงานคนสุดท้ายที่ดำเนินการเสร็จสมบูรณ์จะเป็น "ผู้ชนะ" และระบบจะส่งค่าของผู้ปฏิบัติงานรายนั้นไปยัง cache

แผนภาพแสดงงาน 3 งานที่ส่งเอาต์พุตไปยังงานถัดไปในเชน ในกรณีนี้ งาน 2 รายการจะสร้างเอาต์พุตที่มีคีย์เดียวกัน ด้วยเหตุนี้ งานถัดไปจึงได้รับคู่คีย์/ค่า 2 คู่ โดยเอาต์พุตที่ขัดแย้งกันรายการหนึ่งจะถูกตัดออก

เนื่องจากคำของานทำงานพร้อมกัน จึงไม่มีการรับประกันลำดับการทำงาน ในตัวอย่างข้างต้น 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 จับคู่คีย์แต่ละรายการกับอาร์เรย์ หากแต่ละคีย์ไม่ซ้ำกัน ผลลัพธ์ที่ได้จะเป็นชุดอาร์เรย์ที่มีองค์ประกอบเดียว

แผนภาพแสดงงาน 3 งานที่ส่งเอาต์พุตที่แตกต่างกันไปยังงานถัดไปในเชน งานถัดไปจะส่งอาร์เรย์ 3 รายการ โดยแต่ละรายการจะใช้สำหรับคีย์เอาต์พุตแต่ละคีย์ แต่ละอาร์เรย์มีสมาชิกเพียง 1 รายการ

หากมีคีย์ที่ทับซ้อนกัน ระบบจะจัดกลุ่มค่าที่เกี่ยวข้องไว้ด้วยกันในอาร์เรย์

แผนภาพแสดงงาน 3 งานที่ส่งเอาต์พุตไปยังงานถัดไปในเชน ในกรณีนี้ งาน 2 รายการจะสร้างเอาต์พุตที่มีคีย์เดียวกัน งานถัดไปจะส่งอาร์เรย์ 2 รายการ โดยแต่ละรายการมีคีย์ 1 รายการ อาร์เรย์หนึ่งมีสมาชิก 2 รายการ เนื่องจากมีเอาต์พุต 2 รายการที่มีคีย์นั้น

การเชื่อมโยงและสถานะการทำงาน

เชนของ OneTimeWorkRequest จะทำงานตามลำดับตราบใดที่งานเสร็จสมบูรณ์ (นั่นคือแสดงผล Result.success()) คำของานอาจล้มเหลวหรือถูกยกเลิกขณะทำงาน ซึ่งส่งผลกระทบต่อคำของานที่ขึ้นต่อกัน

เมื่อ OneTimeWorkRequest แรกอยู่ในคิวในเชนของคำของาน คำของานที่ตามมาทั้งหมดจะถูกบล็อกจนกว่างานของคำของานแรกจะเสร็จสมบูรณ์

แผนภาพแสดงชุดงาน ระบบจะจัดคิวงานแรกไว้ และบล็อกงานที่ตามมาทั้งหมดจนกว่างานแรกจะเสร็จสิ้น

เมื่อจัดคิวและเป็นไปตามข้อจำกัดของงานทั้งหมดแล้ว คำของานแรกจะเริ่มทำงาน หากงานเสร็จสมบูรณ์ในรูท OneTimeWorkRequest หรือ List<OneTimeWorkRequest> (นั่นคือแสดงผล Result.success()) ระบบจะจัดคิวคำของานที่ขึ้นต่อกันชุดถัดไป

แผนภาพแสดงชุดงาน งานแรกสำเร็จ และงานที่ตามมาทันที 2 งานจะอยู่ในคิว งานที่เหลือจะถูกบล็อกจนกว่างานก่อนหน้าจะเสร็จสิ้น

ตราบใดที่คำของานแต่ละรายการเสร็จสมบูรณ์ รูปแบบเดียวกันนี้จะเผยแพร่ผ่านคำของานที่เหลือในเชนจนกว่างานทั้งหมดในเชนจะเสร็จสมบูรณ์ แม้ว่าจะเป็นกรณีที่ง่ายที่สุดและมักเป็นที่ต้องการ แต่สถานะข้อผิดพลาดก็มีความสำคัญไม่แพ้กัน

เมื่อเกิดข้อผิดพลาดขณะที่เวิร์กเกอร์กำลังประมวลผลคำของาน คุณสามารถลองส่งคำขอนั้นอีกครั้งตามนโยบาย Backoff ที่คุณกำหนด การลองส่งคำขอที่เป็นส่วนหนึ่งของเชนอีกครั้งหมายความว่าระบบจะลองส่งคำขอนั้นอีกครั้งด้วยข้อมูลอินพุตที่ระบุไว้ งานที่ทำงานพร้อมกันจะไม่ได้รับผลกระทบ

แผนภาพแสดงชุดงาน งานหนึ่งล้มเหลว แต่มีการกำหนดนโยบาย Backoff ไว้ งานดังกล่าวจะทำงานอีกครั้งหลังจากผ่านไประยะเวลาหนึ่งที่เหมาะสม งานที่อยู่หลังจากนั้นในเชนจะถูกบล็อกจนกว่างานจะทำงานสำเร็จ

ดูข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดกลยุทธ์การลองใหม่ที่กำหนดเองได้ที่นโยบายการลองใหม่และการ Backoff

หากนโยบายการลองใหม่นั้นไม่ได้กำหนดไว้หรือหมดลง หรือคุณเข้าสู่สถานะที่ OneTimeWorkRequest แสดงผลเป็น Result.failure() ระบบจะทำเครื่องหมายคำของานนั้นและคำของานที่เกี่ยวข้องทั้งหมดเป็น FAILED.

แผนภาพแสดงชุดงาน งาน 1 รายการล้มเหลวและลองอีกครั้งไม่ได้ ด้วยเหตุนี้ งานทั้งหมดที่อยู่หลังจากนั้นในเชนจึงล้มเหลวด้วย

ตรรกะเดียวกันนี้จะใช้เมื่อมีการยกเลิก OneTimeWorkRequest คำของานที่ขึ้นต่อกันจะได้รับการทำเครื่องหมายเป็นCANCELLEDด้วย และงานดังกล่าวจะไม่ได้รับการดำเนินการ

แผนภาพแสดงชุดงาน ยกเลิกงาน 1 รายการแล้ว ด้วยเหตุนี้ งานทั้งหมดที่ตามมาในเชนจึงถูกยกเลิกด้วย

โปรดทราบว่าหากคุณเพิ่มคำของานลงในเชนที่มีคำของานที่ล้มเหลวหรือถูกยกเลิก คำของานที่เพิ่มใหม่จะได้รับการทำเครื่องหมายเป็นFAILEDหรือCANCELLEDตามลำดับด้วย หากต้องการขยายงานของเชนที่มีอยู่ โปรดดู APPEND_OR_REPLACE ใน ExistingWorkPolicy

เมื่อสร้างเชนของคำของาน คำของานที่ขึ้นต่อกันควรกำหนดนโยบายการลองใหม่เพื่อให้แน่ใจว่างานจะเสร็จสมบูรณ์อย่างทันท่วงทีเสมอ คำของานที่ล้มเหลวอาจส่งผลให้เชนไม่สมบูรณ์และ/หรือสถานะที่ไม่คาดคิด

ดูข้อมูลเพิ่มเติมได้ที่การยกเลิกและการหยุดงาน