Chuỗi công việc

WorkManager cho phép bạn tạo và sắp xếp chuỗi công việc vào hàng đợi để chỉ định nhiều tác vụ phụ thuộc và xác định thứ tự thực hiện. Chức năng này đặc biệt hữu ích khi bạn cần thực hiện nhiều tác vụ theo thứ tự cụ thể.

Để tạo chuỗi công việc, bạn có thể dùng WorkManager.beginWith(OneTimeWorkRequest) hoặc WorkManager.beginWith(List<OneTimeWorkRequest>). Mỗi phần trả về một phiên bản của WorkContinuation.

Sau đó, có thể dùng WorkContinuation để thêm phiên bản OneTimeWorkRequest phụ thuộc bằng cách sử dụng then(OneTimeWorkRequest) hoặc then(List<OneTimeWorkRequest>) .

Mỗi lời gọi WorkContinuation.then(...) sẽ trả về WorkContinuation phiên bản mới. Nếu thêm List các thực thể OneTimeWorkRequest, bạn có thể thực hiện song song những yêu cầu này.

Cuối cùng, bạn có thể dùng phương thức WorkContinuation.enqueue() để enqueue() chuỗi WorkContinuation.

Hãy xem một ví dụ. Trong ví dụ này, 3 công việc khác nhau của Worker được định cấu hình để chạy (có thể thực hiện song song). Sau đó, kết quả của các Worker này là liên kết và chuyển sang lưu dữ liệu công việc của Worker vào bộ nhớ đệm. Cuối cùng, dữ liệu đầu ra của công việc đó được chuyển vào một Worker đã tải lên. Công cụ này sẽ tải kết quả lên máy chủ từ xa.

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();

Hợp nhất dữ liệu đầu vào

Khi bạn liên kết phiên bản OneTimeWorkRequest, dữ liệu đầu ra của yêu cầu công việc chính được chuyển ở dạng dữ liệu đầu vào đến yêu cầu công việc phụ. Vì vậy, trong ví dụ trên, dữ liệu đầu ra của plantName1, plantName2plantName3 sẽ được chuyển ở dạng dữ liệu đầu vào đến yêu cầu cache.

Để quản lý dữ liệu đầu vào từ nhiều yêu cầu công việc chính, WorkManager sử dụng InputMerger.

WorkManager cung cấp hai loại InputMerger khác nhau:

  • OverwritingInputMerger cố gắng thêm tất cả các khoá từ dữ liệu đầu vào đến dữ liệu đầu ra. Trong trường hợp xảy ra xung đột, mã này sẽ ghi đè tất cả các khoá đã thiết lập trước đó.

  • ArrayCreatingInputMerger cố gắng hợp nhất dữ liệu đầu vào để tạo mảng khi cần.

Nếu có trường hợp sử dụng cụ thể hơn, bạn có thể tự viết bằng cách phân lớp con InputMerger.

OverwritingInputMerger

OverwritingInputMerger là phương thức hợp nhất mặc định. Nếu có xung đột khoá trong quá trình hợp nhất, giá trị mới nhất của khoá sẽ ghi đè bất kỳ phiên bản nào trước đó trong kết quả dữ liệu đầu ra.

Ví dụ: Nếu mỗi cây nhập có một khoá khớp với tên biến thể tương ứng ("plantName1", "plantName2""plantName3"), dữ liệu chuyển đến worker cache sẽ có ba cặp khoá-giá trị.

Sơ đồ thể hiện ba công việc chuyển nhiều dữ liệu đầu ra đến công việc tiếp theo trong chuỗi. Vì tất cả ba kết quả đầu ra có các khoá khác nhau, nên công việc tiếp theo nhận được ba cặp giá trị-khoá.

Nếu có xung đột, worker gần nhất sẽ hoàn tất “wins” rồi giá trị được chuyển đến cache.

Sơ đồ thể hiện ba công việc chuyển dữ liệu đầu ra đến công việc tiếp theo trong chuỗi. Trong trường hợp này, hai trong số các công việc đó tạo dữ liệu đầu ra bằng cùng một khoá. Vì vậy, công việc tiếp theo nhận được hai cặp khoá/giá trị, trong đó một dữ liệu đầu ra xung đột bị bỏ lại.

Vì yêu cầu công việc chạy song song nên không thể đảm bảo thứ tự thực hiện. Trong ví dụ trên, plantName1 có thể chứa giá trị của "tulip" hoặc "elm", tuỳ thuộc vào việc giá trị nào được ghi gần đây nhất. Nếu có nguy cơ xung đột khoá và bạn cần duy trì toàn bộ dữ liệu đầu ra hợp nhất thì ArrayCreatingInputMerger có thể là lựa chọn tốt hơn.

ArrayCreatingInputMerger

Trong ví dụ trên, giả sử nếu muốn duy trì dữ liệu đầu ra từ tất cả các Worker tên cây, chúng ta nên dùng 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 ghép nối từng khoá với một mảng. Nếu mỗi khoá là không trùng lặp, kết quả của bạn sẽ là các chuỗi mảng một phần tử.

Sơ đồ thể hiện ba công việc chuyển nhiều dữ liệu đầu ra đến công việc tiếp theo trong chuỗi. Công việc tiếp theo chuyển ba mảng, mỗi mảng cho một khoá đầu ra. Mỗi mảng có một thành viên.

Nếu có bất kỳ xung đột khoá nào, mọi giá trị tương ứng sẽ được nhóm vào cùng một mảng.

Sơ đồ thể hiện ba công việc chuyển dữ liệu đầu ra đến công việc tiếp theo trong chuỗi. Trong trường hợp này, hai trong số các công việc đó tạo dữ liệu đầu ra bằng cùng một khoá. Công việc tiếp theo chuyển hai mảng, mỗi mảng cho một khoá. Vì có hai kết quả đầu ra với khoá đó nên một trong những mảng này có hai thành phần.

Trạng thái chuỗi công việc

Các chuỗi OneTimeWorkRequest thực thi tuần tự miễn là công việc hoàn thành (tức là các chuỗi này trả về Result.success()). Yêu cầu công việc có thể không thành công hoặc bị huỷ trong quá trình thực hiện, từ đó tác động đến các yêu cầu công việc phụ thuộc.

Khi OneTimeWorkRequest đầu tiên được xếp vào hàng đợi trong chuỗi yêu cầu công việc, toàn bộ yêu cầu công việc tiếp theo sẽ bị chặn lại cho đến khi công việc trong yêu cầu công việc đầu tiên đã hoàn tất.

Sơ đồ thể hiện chuỗi công việc. Công việc đầu tiên đã được thêm vào hàng đợi; tất cả công việc kế tiếp bị chặn lại cho đến khi công việc đầu tiên kết thúc.

Sau khi xếp vào hàng đợi và đáp ứng toàn bộ các quy tắc trong công việc, yêu cầu công việc đầu tiên bắt đầu tiến hành. Nếu công việc đã hoàn tất trong OneTimeWorkRequest gốc hoặc List<OneTimeWorkRequest> (tức kết quả trả về là Result.success()), nhóm yêu cầu công việc phụ thuộc tiếp theo sẽ được xếp vào hàng đợi.

Sơ đồ thể hiện chuỗi công việc. Khi công việc đầu tiên đã hoàn tất thành công, hai công việc kế tiếp sẽ được thêm ngay vào hàng đợi. Các công việc còn lại đều bị chặn trước khi hoàn thành những công việc này.

Chỉ cần từng yêu cầu công việc đều hoàn tất thành công, mô hình này sẽ được áp dụng với phần còn lại của chuỗi yêu cầu công việc cho đến khi hoàn thành toàn bộ công việc trong chuỗi. Mặc dù là vấn đề đơn giản nhất và thường được ưu tiên, việc xử lý trạng thái lỗi cũng không kém phần quan trọng.

Nếu xảy ra lỗi trong lúc worker xử lý yêu cầu công việc, bạn có thể thử lại yêu cầu đó theo chính sách đợi bạn xác định. Việc thử lại yêu cầu là một phần của chuỗi, tức là sẽ chỉ yêu cầu đó được thực hiện lại bằng dữ liệu đầu vào đã cấp. Mọi công việc chạy song song sẽ không bị ảnh hưởng.

Sơ đồ thể hiện chuỗi công việc. Một trong các công việc không thành công nhưng đã xác định được chính sách đợi. Công việc đó sẽ được tiến hành lại sau một khoảng thời gian thích hợp. Các câu việc tiếp theo trong chuỗi sẽ bị chặn lại cho đến khi công việc này hoàn tất.

Để biết thêm thông tin về cách xác định chiến lược thử lại tuỳ chỉnh, hãy xem phần Thử lại và chính sách đợi.

Nếu không xác định được chính sách thử lại hay chính sách này đã hết hiệu lực hoặc bạn đã đạt được một số trạng thái mà OneTimeWorkRequest trả về Result.failure() thì yêu cầu công việc đó và toàn bộ các yêu cầu công việc phụ thuộc được đánh dấu thành FAILED.

Sơ đồ thể hiện chuỗi công việc. Một công việc không thực hiện thành công và không thể thử lại. Do đó, tất cả các công việc tiếp theo đều không thành công.

Hệ thống sẽ áp dụng cùng logic đó khi OneTimeWorkRequest bị huỷ. Hệ thống sẽ đánh dấu mọi yêu cầu công việc phụ thuộc là CANCELLED và công việc sẽ không được thực thi.

Sơ đồ thể hiện chuỗi công việc. Một công việc đã bị huỷ. Do đó, toàn bộ công việc tiếp theo trong chuỗi này sẽ bị huỷ.

Lưu ý rằng nếu bạn nối yêu cầu công việc vào đầu một chuỗi thực hiện không thành công hoặc đã huỷ yêu cầu công việc, thì yêu cầu công việc vừa nối cũng sẽ bị đánh dấu tương ứng là FAILED hoặc CANCELLED. Nếu bạn muốn mở rộng phạm vi công việc của chuỗi hiện tại, hãy xem APPEND_OR_REPLACE trong ExistingWorkPolicy.

Khi tạo các chuỗi yêu cầu công việc, yêu cầu công việc phụ thuộc phải xác định chính sách thử lại để đảm bảo rằng luôn hoàn thành công việc đúng hạn. Yêu cầu công việc không thành công có thể dẫn đến chuỗi chưa hoàn chỉnh và/hoặc trạng thái không mong muốn.

Để biết thêm thông tin, hãy xem phần Huỷ và dừng công việc.