งานเชน

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 งานทำงาน (อาจทำงานแบบขนานกัน) จากนั้นระบบจะรวมผลลัพธ์ของ 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 พยายามผสานอินพุตและสร้างอาร์เรย์เมื่อจำเป็น

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

OverwritingInputMerger

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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