Łączenie łańcuchów

WorkManager pozwala utworzyć i umieścić w kolejce łańcuch pracy, który określa wiele zależnych zadań i określa, w jakiej kolejności należy je uruchomić. Ten jest szczególnie przydatna, gdy należy uruchomić kilka zadań w określonym zamówieniu.

Do utworzenia łańcucha zadań możesz użyć WorkManager.beginWith(OneTimeWorkRequest) lub WorkManager.beginWith(List<OneTimeWorkRequest>) , z których każdy zwraca wystąpienie WorkContinuation.

Za pomocą funkcji WorkContinuation można następnie dodać zależne elementy OneTimeWorkRequest instancji korzystających z funkcji then(OneTimeWorkRequest). lub then(List<OneTimeWorkRequest>). ,

Każde wywołanie funkcji WorkContinuation.then(...) zwraca nowe wystąpienie WorkContinuation. Jeśli dodasz List z OneTimeWorkRequest instancji, te żądania mogą być uruchamiane równolegle.

Na koniec możesz użyć funkcji WorkContinuation.enqueue() do enqueue() Twojego łańcucha WorkContinuation.

Przeanalizujmy przykład. W tym przykładzie 3 różne zadania instancji roboczej to skonfigurowane do działania (potencjalnie równolegle). Wyniki tych procesów roboczych są a następnie został dołączony i przekazany do zadania instancji roboczej buforowania. Dane wyjściowe tego narzędzia jest przekazywane do instancji roboczej przesyłania, która przesyła wyniki do modułu zdalnego serwera.

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

Fuzje danych wejściowych

Gdy połączysz tyle instancji: OneTimeWorkRequest, dane wyjściowe instancji nadrzędnej będą działać są przekazywane do elementów podrzędnych jako dane wejściowe. W powyższym przykładzie dane wyjściowe plantName1, plantName2 i plantName3 byłyby przekazywane jako danych wejściowych do żądania cache.

Aby zarządzać danymi wejściowymi pochodzącymi z wielu nadrzędnych żądań roboczych, WorkManager używa InputMerger

WorkManager udostępnia 2 różne typy znaczników InputMerger:

  • OverwritingInputMerger próbuje dodać do danych wyjściowych wszystkie klawisze ze wszystkich wejść. W przypadku konfliktów zastąpią one wcześniej ustawione klucze.

  • ArrayCreatingInputMerger próbuje scalić dane wejściowe, w razie potrzeby tworząc tablice.

Jeśli masz bardziej szczegółowy przypadek użycia, możesz napisać własny, stosując klasyfikację podklasyczną. InputMerger

Nadpisanie danych wejściowych

Domyślną metodą scalania jest OverwritingInputMerger. Jeśli klucz podczas scalania konflikty, najnowsza wartość klucza zastąpi wszystkie starsze wersje w wynikowych danych wyjściowych.

Jeśli na przykład dane wejściowe rośliny mają klucz pasujący do nazw zmiennych ("plantName1", "plantName2" i "plantName3"), a następnie dane przekazywane do instancji roboczej cache będą miały 3 pary klucz-wartość.

Schemat przedstawiający 3 zadania przekazujące różne dane wyjściowe do następnego zadania w łańcuchu. Wszystkie 3 dane wyjściowe mają różne klucze, dlatego następne zadanie otrzymuje 3 pary klucz-wartość.

W przypadku konfliktu to ostatni robot, który uzupełni „wygrane” i jego wartość. jest przekazywana do funkcji cache.

Schemat przedstawiający 3 zadania przekazujące dane wyjściowe do następnego zadania w łańcuchu. W tym przypadku 2 z tych zadań generują dane wyjściowe z tym samym kluczem. W rezultacie następne zadanie otrzymuje 2 pary klucz-wartość, przy czym jedna z wyjść powodujących konflikt została usunięta.

Żądania służbowe są uruchamiane równolegle, więc nie masz gwarancji dla w kolejności ich wyświetlania. W powyższym przykładzie plantName1 może zawierać element wartość "tulip" lub "elm", w zależności od tego, która wartość jest zapisana. na końcu. Jeśli istnieje możliwość wystąpienia kluczowego konfliktu i musisz zachować wszystkie dane wyjściowe danych w ramach fuzji, lepszym rozwiązaniem będzie ArrayCreatingInputMerger.

Scalanie_tablic

W powyższym przykładzie, ponieważ chcemy zachować wyniki uzyskane ze wszystkich zakładów nazwa Workers, powinniśmy użyć ArrayCreatingInputMerger.

Kotlin

val cache: OneTimeWorkRequest = OneTimeWorkRequestBuilderP<lantWorker(>)
   .setInputMerger(ArrayCreatingInputMerger::class)
   .setConstraints(constraints)
   .build()

Java

OneTimeWorkRequest cache = new OneTimeWorkRequest.Builder(PlantWorker.class)
       .setInputMerger(ArrayCreatingInputMerger.class)
       .setConstraints(constraints)
       .build();

ArrayCreatingInputMerger paruje każdy klucz z tablicą. Jeśli każdy z kluczy jest unikalny, wynik to seria jednoelementowych tablic.

Schemat przedstawiający 3 zadania przekazujące różne dane wyjściowe do następnego zadania w łańcuchu. Kolejne zadanie przekazuje 3 tablice, po 1 dla każdego klucza wyjściowego. Każda tablica ma jednego element.

Jeśli wystąpią kolizje kluczy, wszystkie odpowiadające im wartości zostaną zgrupowane razem w tablicy.

Schemat przedstawiający 3 zadania przekazujące dane wyjściowe do następnego zadania w łańcuchu. W tym przypadku 2 z tych zadań generują dane wyjściowe z tym samym kluczem. Następne zadanie przekazuje 2 tablice, po 1 dla każdego klucza. Jedna z tych tablic ma 2 elementy, ponieważ były to 2 wyjściowe dane z tym kluczem.

Łańcuch i stany pracy

Łańcuchy OneTimeWorkRequest są realizowane sekwencyjnie tak długo, jak długo działają kończy się poprawnie (tzn. zwraca Result.success()). Służbowy mogą nie zostać zrealizowane lub mogą zostać anulowane podczas wykonywania, co ma wpływ na dalszy ciąg zależnych od pracy.

Gdy pierwszy element (OneTimeWorkRequest) zostanie umieszczony w kolejce w łańcuchu żądań, wszystkie kolejne żądania dotyczące pracy są blokowane do czasu wykonania tego pierwszego zadania. .

Diagram przedstawiający łańcuch zadań. Pierwsze zadanie jest umieszczone w kolejce. Wszystkie kolejne zadania są blokowane, dopóki nie zakończy się pierwsze.

Po dodaniu do kolejki i spełnieniu wszystkich ograniczeń roboczych pierwsze żądanie robocze zaczyna biegać. Jeśli praca zostanie ukończona w katalogu głównym OneTimeWorkRequest lub List<OneTimeWorkRequest> (tzn. zwraca błąd Result.success()), następny zestaw zależnych żądań roboczych będzie dodano do kolejki.

Diagram przedstawiający łańcuch zadań. Pierwsze zadanie zakończyło się sukcesem, a dwóch jego następców zostaje dodanych do kolejki. Pozostałe zadania zostały zablokowane, ponieważ poprzednie zadania zostały zakończone.

Dopóki każde żądanie służbowe zostanie zrealizowane, ten sam wzorzec jest rozpowszechniana przez pozostałą część łańcucha żądań, aż cała praca w łańcuch jest zakończony. Choć jest to najprostszy i najczęściej preferowany przypadek, błąd są równie ważne.

Jeśli błąd wystąpi podczas przetwarzania Twojego żądania służbowego przez pracownika, możesz ponów żądanie zgodnie z zasadami ponownych prób definicjami. Ponowienie żądania, które jest częścią łańcucha, oznacza, że tylko to żądanie ponowiona, korzystając z dostarczonych danych wejściowych. Równoległa praca będzie co się nie zmienia.

Diagram przedstawiający łańcuch zadań. Jedno z zadań zakończyło się niepowodzeniem, ale zdefiniowano zasadę ponowienia. Zadanie zostanie ponownie uruchomione po upływie odpowiedniego czasu. Kolejne zadania w łańcuchu będą blokowane, dopóki nie zostaną uruchomione.

Więcej informacji na temat definiowania niestandardowych strategii ponownych prób znajdziesz w artykule Ponawianie próby i czas do ponowienia Zasady.

Jeśli te zasady są niezdefiniowane lub wyczerpane albo jeśli w inny sposób osiągniesz stan, w którym OneTimeWorkRequest zwraca Result.failure(), a następnie to żądanie robocze i wszystkie zależne żądania pracy są oznaczone jako FAILED.

Diagram przedstawiający łańcuch zadań. 1 zadanie zakończyło się niepowodzeniem i nie można go ponowić. W rezultacie wszystkie kolejne zadania w łańcuchu również kończą się niepowodzeniem.

Te same zasady obowiązują w przypadku anulowania polecenia OneTimeWorkRequest. Dowolne zależne Żądania robocze są również oznaczane jako CANCELLED, a ich zadania nie będą wykonywane.

Diagram przedstawiający łańcuch zadań. 1 zadanie zostało anulowane. W związku z tym wszystkie kolejne zadania w łańcuchu również zostaną anulowane.

Pamiętaj, że w przypadku dołączenia większej liczby żądań roboczych do łańcucha, który zakończył się niepowodzeniem lub Użytkownik anulował zlecenia robocze, Twoje nowo dołączone zlecenie pracy również zostanie oznaczony odpowiednio FAILED lub CANCELLED. Jeśli chcesz przedłużyć pracę istniejącej sieci, wyświetl APPEND_OR_REPLACE w Istniejące zasady pracy.

Przy tworzeniu łańcuchów żądań służbowych zależne żądania powinny określać ponawiaj próby, aby zapewnić szybkie zakończenie pracy. Nieudane żądania robocze mogą skutkować niepełnymi łańcuchami lub nieoczekiwanym stanem.

Więcej informacji znajdziesz w sekcji Anulowanie i zatrzymywanie Praca.