작업 체이닝

WorkManager를 사용하면 여러 종속 작업을 지정하고 실행 순서를 정의하는 작업 체인을 만들고 큐에 추가할 수 있습니다. 체이닝 기능은 특정 순서로 여러 작업을 실행해야 할 때 특히 유용합니다.

작업 체인을 만들려면 각각 WorkContinuation 인스턴스를 반환하는 WorkManager.beginWith(OneTimeWorkRequest) 또는 WorkManager.beginWith(List<OneTimeWorkRequest>)를 사용하면 됩니다.

그런 다음 WorkContinuation을 사용하여 then(OneTimeWorkRequest) 또는 then(List<OneTimeWorkRequest>)을 통해 종속 OneTimeWorkRequest 인스턴스를 추가할 수 있습니다.

WorkContinuation.then(...)이 호출될 때마다 WorkContinuation 인스턴스가 반환됩니다. OneTimeWorkRequest 인스턴스의 List를 추가하면 이러한 요청이 잠재적으로 동시에 실행될 수 있습니다.

마지막으로 WorkContinuation.enqueue() 메서드를 사용하여 WorkContinuation 체인을 큐에 추가(enqueue())할 수 있습니다.

예를 살펴보겠습니다. 예에서 작업자 작업 세 개가 잠재적으로 동시에 실행되도록 구성됩니다. 그런 다음 이러한 작업자의 결과가 결합되어 작업자 작업 캐싱에 전달됩니다. 마지막으로 이 작업의 출력이 업로드 작업자에 전달되며, 업로드 작업자는 결과를 원격 서버에 업로드합니다.

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 유형은 두 가지입니다.

  • OverwritingInputMerger는 모든 입력의 키를 출력에 모두 추가하려고 시도합니다. 충돌이 발생하면 이전에 설정한 키를 덮어씁니다.

  • ArrayCreatingInputMerger는 입력을 병합하려고 시도하며 필요한 경우 배열을 만듭니다.

더 구체적인 사용 사례가 있다면 InputMerger를 서브클래스로 분류하여 직접 작성할 수 있습니다.

OverwritingInputMerger

OverwritingInputMerger는 기본 병합 메서드입니다. 병합에 키 충돌이 있다면 최신 키 값이 결과 출력 데이터의 이전 버전을 모두 덮어씁니다.

예를 들어 식물 입력에 각각의 변수 이름("plantName1", "plantName2", "plantName3")과 일치하는 키가 있으면 cache 작업자에 전달된 데이터에는 키-값 쌍이 세 개 있습니다.

체인에서 다음 작업에 서로 다른 출력을 전달하는 작업 세 개를 보여주는 다이어그램입니다. 출력 세 개의 키가 모두 다르므로 다음 작업에서는 키-값 쌍 세 개를 수신합니다.

충돌이 발생하면 마지막으로 완료한 작업자가 '승리'하고 값이 cache로 전달됩니다.

체인에서 다음 작업에 출력을 전달하는 작업 세 개를 보여주는 다이어그램입니다. 이 경우 작업 중 두 개는 동일한 키가 포함된 출력을 생성합니다. 그 결과 다음 작업은 충돌하는 출력 중 하나가 삭제된 키-값 쌍 2개를 수신합니다.

작업 요청은 동시에 실행되므로 요청이 실행되는 순서는 보장되지 않습니다. 위 예에서 plantName1은 마지막으로 작성된 값에 따라 "tulip" 또는 "elm" 값을 보유할 수 있습니다. 키 충돌 가능성이 있고 병합에서 모든 출력 데이터를 유지해야 한다면 ArrayCreatingInputMerger가 더 나은 옵션일 수 있습니다.

ArrayCreatingInputMerger

위 예에서 모든 식물 이름 작업자의 출력을 유지하려면 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는 각 키를 배열과 페어링합니다. 각 키가 고유하면 결과는 일련의 단일 요소로 배열됩니다.

체인에서 다음 작업에 서로 다른 출력을 전달하는 작업 세 개를 보여주는 다이어그램입니다. 다음 작업에는 출력 키마다 하나씩 총 세 개의 배열이 전달됩니다. 각 배열에는 구성요소가 하나 있습니다.

키 충돌이 발생하면 상응하는 값이 한 배열로 그룹화됩니다.

체인에서 다음 작업에 출력을 전달하는 작업 세 개를 보여주는 다이어그램입니다. 이 경우 작업 중 두 개는 동일한 키가 포함된 출력을 생성합니다. 다음 작업에는 키마다 하나씩 총 두 개의 배열이 전달됩니다. 이러한 배열 중 하나에는 구성요소가 두 개 있습니다. 키가 있는 출력이 두 개였기 때문입니다.

체이닝 및 작업 상태

OneTimeWorkRequest 체인은 작업이 성공적으로 완료되면, 즉 Result.success()를 반환하면 순차적으로 실행됩니다. 작업 요청은 실행 중에 실패하거나 취소될 수 있어서 종속 작업 요청에 후속 영향을 미칩니다.

첫 번째 OneTimeWorkRequest가 작업 요청 체인에서 큐에 추가되면 첫 번째 작업 요청의 작업이 완료될 때까지 모든 후속 작업 요청이 차단됩니다.

작업 체인을 보여주는 다이어그램입니다. 첫 번째 작업이 큐에 추가되면 첫 번째 작업이 완료될 때까지 모든 후속 작업이 차단됩니다.

큐에 추가되고 모든 작업 제약조건이 충족되면 첫 번째 작업 요청이 실행되기 시작합니다. 작업이 루트 OneTimeWorkRequest 또는 List<OneTimeWorkRequest>에서 성공적으로 완료되면, 즉 Result.success()를 반환하면 다음 종속 작업 요청 세트가 큐에 추가됩니다.

작업 체인을 보여주는 다이어그램입니다. 첫 번째 작업이 성공했고 두 직속 후속 작업이 큐에 추가됩니다. 나머지 작업은 이전 작업이 완료되도록 차단됩니다.

각 작업 요청이 성공적으로 완료된다면 체인의 모든 작업이 완료될 때까지 작업 요청 체인의 나머지 부분 전체에 이와 동일한 패턴이 적용됩니다. 이 사례는 가장 간단하고 주로 선호되지만 오류 상태를 매우 중요하게 다뤄야 합니다.

작업자가 작업 요청을 처리하는 동안 오류가 발생하면 개발자가 정의한 백오프 정책에 따라 요청을 재시도할 수 있습니다. 체인에 속한 요청을 재시도하면 제공된 입력 데이터로 해당 요청만 재시도됩니다. 동시에 실행되는 모든 작업은 영향을 받지 않습니다.

작업 체인을 보여주는 다이어그램입니다. 작업 중 하나가 실패했지만 백오프 정책이 정의되었습니다. 적절한 시간이 지나면 실패했던 작업이 다시 실행됩니다. 체인에 있는 후속 작업은 실패했던 작업이 성공적으로 실행될 때까지 차단됩니다.

맞춤 재시도 전략 정의에 관한 자세한 내용은 재시도 및 백오프 정책을 참고하세요.

재시도 정책이 정의되어 있지 않거나 없는 경우 또는 OneTimeWorkRequestResult.failure()를 반환하는 상태에 도달하면 작업 요청과 모든 종속 작업 요청이 FAILED.로 표시됩니다.

작업 체인을 보여주는 다이어그램입니다. 작업 하나가 실패했으며 다시 시도할 수 없습니다. 따라서 체인에 있는 모든 후속 작업도 실패합니다.

OneTimeWorkRequest가 취소되면 동일한 로직이 적용됩니다. 종속 작업 요청도 CANCELLED로 표시되고 작업이 실행되지 않습니다.

작업 체인을 보여주는 다이어그램입니다. 작업 하나가 취소되었습니다. 따라서 체인에 있는 모든 후속 작업도 취소됩니다.

실패하거나 취소된 작업 요청이 있는 체인에 더 많은 작업 요청을 추가하면 새로 추가된 작업 요청도 각각 FAILED 또는 CANCELLED로 표시됩니다. 기존 체인의 작업을 확장하려는 경우 ExistingWorkPolicyAPPEND_OR_REPLACE를 참고하세요.

작업 요청 체인을 만들 때 종속 작업 요청은 작업이 항상 적시에 완료되도록 재시도 정책을 정의해야 합니다. 작업 요청에 실패하면 체인이 불완전하거나 예상치 못한 상태가 될 수 있습니다.

자세한 내용은 작업 취소 및 중지를 참고하세요.