งานเชน

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 หลายรายการ

มาดูตัวอย่างกัน ในตัวอย่างนี้ มีการกำหนดค่างาน Worker 3 รายการให้ทำงาน (อาจทำงานพร้อมกัน) จากนั้นระบบจะรวมผลลัพธ์ของโหนดเหล่านี้และส่งต่อไปยังงานโหนดแคช สุดท้าย ระบบจะส่งเอาต์พุตของงานนั้นไปยังเวิร์กเกอร์การอัปโหลด ซึ่งจะอัปโหลดผลลัพธ์ไปยังเซิร์ฟเวอร์ระยะไกล

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 มีให้มีอยู่ 2 ประเภท ดังนี้

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

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

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

OverwritingInputMerger

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

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

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

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

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

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

ArrayCreatingInputMerger

สําหรับตัวอย่างข้างต้น เนื่องจากเราต้องการเก็บรักษาเอาต์พุตจาก Plant ทั้งหมดที่มีชื่อเป็น 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 รายการไว้แล้ว งานที่เหลือจะบล็อกจนกว่างานก่อนหน้าจะเสร็จสิ้น

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

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

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

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

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

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

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

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

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

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

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