งานเชน

WorkManager ช่วยให้คุณสร้างและจัดคิวงานแบบลูกโซ่ที่ระบุ งานที่ขึ้นต่อกันหลายงานและกำหนดลำดับการเรียกใช้ ฟังก์ชันการทำงานนี้มีประโยชน์อย่างยิ่งเมื่อคุณต้องการเรียกใช้หลายๆ งานตามลำดับที่เฉพาะเจาะจง

หากต้องการสร้างเชนของงาน คุณสามารถใช้ WorkManager.beginWith(OneTimeWorkRequest) หรือ WorkManager.beginWith(List<OneTimeWorkRequest>) ซึ่งแต่ละรายการจะแสดงอินสแตนซ์ของ WorkContinuation

จากนั้นจะใช้ WorkContinuation เพื่อเพิ่มอินสแตนซ์ OneTimeWorkRequest ที่ขึ้นต่อกันได้โดยใช้ then(OneTimeWorkRequest) หรือ then(List<OneTimeWorkRequest>)

การเรียกใช้ WorkContinuation.then(...) ทุกครั้งจะแสดงผลอินสแตนซ์ใหม่ของ WorkContinuation หากคุณเพิ่มอินสแตนซ์ ListOneTimeWorkRequest คำขอเหล่านี้อาจทำงานแบบคู่ขนานได้

สุดท้าย คุณสามารถใช้วิธี WorkContinuation.enqueue() เพื่อenqueue()เชนของWorkContinuationได้

มาดูตัวอย่างกัน ในตัวอย่างนี้ งาน Worker 3 งานที่แตกต่างกัน ได้รับการกำหนดค่าให้ทำงาน (อาจทำงานแบบขนาน) จากนั้นระบบจะรวมผลลัพธ์ของผู้ปฏิบัติงานเหล่านี้และส่งต่อไปยังงานของผู้ปฏิบัติงานที่แคช สุดท้าย ระบบจะส่งเอาต์พุตของงานนั้นไปยัง 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();

Input Mergers

เมื่อเชื่อมโยงอินสแตนซ์ OneTimeWorkRequest เอาไว้ ระบบจะส่งเอาต์พุตของคำขอ งานหลักเป็นอินพุตไปยังอินสแตนซ์ย่อย ดังนั้นในตัวอย่างข้างต้น ระบบจะส่งเอาต์พุตของ plantName1, plantName2 และ plantName3 เป็นอินพุตไปยังคำขอ cache

WorkManager ใช้ InputMerger เพื่อจัดการอินพุตจากคำของานหลักหลายรายการ

InputMerger ที่ WorkManager มีให้มี 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 รายการ โดยแต่ละรายการมีคีย์ อาร์เรย์หนึ่งมีสมาชิก 2 รายการ เนื่องจากมีเอาต์พุต 2 รายการที่มีคีย์นั้น

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

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

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

แผนภาพแสดงห่วงโซ่งาน ระบบจะจัดคิวงานแรก ส่วนงานอื่นๆ ทั้งหมดจะถูกบล็อกจนกว่างานแรกจะเสร็จสิ้น

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

แผนภาพแสดงห่วงโซ่งาน งานแรกสำเร็จแล้ว และงาน 2 งานที่ต่อจากงานแรกโดยตรงจะเข้าคิว ระบบจะบล็อกงานที่เหลือจนกว่างานก่อนหน้าจะเสร็จสิ้น

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

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

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

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

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

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

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

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

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

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

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