Wiederholen fehlgeschlagener Aktivitäten - AWS Flow Framework für Java

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Wiederholen fehlgeschlagener Aktivitäten

Gelegentlich schlagen Aktivitäten aus temporären Gründen fehl, z. B. aufgrund eines vorübergehenden Verbindungsverlusts. In anderen Fällen wird die Aktivität möglicherweise erfolgreich durchgeführt, daher besteht das geeignete Verfahren zum Umgang mit dem Aktivitätsfehler häufig im (ggf. mehrmaligen) Wiederholen der Aktivität.

Es gibt verschiedene Strategien zum Wiederholen von Aktivitäten. Welche am besten geeignet ist, hängt von den Details in Ihrem Workflow ab. Die Strategien lassen sich grundsätzlich in drei Kategorien einteilen:

  • Bei der "Wiederholen bis zum Erfolg"-Strategie wird die Aktivität einfach so oft wiederholt, bis sie abgeschlossen wird.

  • Die exponentielle Wiederholungsstrategie verlängert das Zeitintervall zwischen den Versuchen exponentiell, bis die Aktivität abgeschlossen wird oder der Vorgang eine bestimmte Stoppmarke erreicht, beispielsweise eine maximale Anzahl an Versuchen.

  • Die benutzerdefinierte Wiederholungsstrategie legt fest, ob und wie die Aktivität nach einem fehlgeschlagenen Versuch wiederholt wird.

In den folgenden Abschnitten wird die Implementierung dieser Strategien beschrieben. In diesem Beispiel nutzen die Workflow-Worker alle eine einzige Aktivität, unreliableActivity, die willkürlich eine der folgenden Verhaltensweisen zeigt:

  • Wird umgehend abgeschlossen

  • Schlägt beabsichtigt fehl durch Überschreiten des Timeout-Wertes

  • Schlägt beabsichtigt fehl durch Ausgeben von IllegalStateException

"Wiederholen bis zum Erfolg"-Strategie

Die einfachste Wiederholungsstrategie besteht darin, die Aktivität nach jedem Fehler zu wiederholen, bis sie schließlich erfolgreich durchgeführt werden kann. Das grundlegende Muster ist:

  1. Implementieren Sie eine verschachtelte TryCatch- oder TryCatchFinally-Klasse in die Eintrittspunktmethode Ihres Workflows.

  2. Führen Sie die Aktivität in doTry aus.

  3. Falls die Aktivität fehlschlägt, ruft das Framework doCatch auf, wodurch die Eintrittspunktmethode erneut ausgeführt wird.

  4. Wiederholen Sie die Schritte 2 bis 3, bis die Aktivität erfolgreich abgeschlossen wird.

Der folgende Workflow implementiert die "Wiederholen bis zum Erfolg"-Strategie. Die Workflow-Schnittstelle wird in RetryActivityRecipeWorkflow implementiert und enthält die Methode runUnreliableActivityTillSuccess, die den Eintrittspunkt des Workflows darstellt. Der Workflow-Worker wird in RetryActivityRecipeWorkflowImpl wie folgt implementiert:

public class RetryActivityRecipeWorkflowImpl implements RetryActivityRecipeWorkflow { @Override public void runUnreliableActivityTillSuccess() { final Settable<Boolean> retryActivity = new Settable<Boolean>(); new TryCatch() { @Override protected void doTry() throws Throwable { Promise<Void> activityRanSuccessfully = client.unreliableActivity(); setRetryActivityToFalse(activityRanSuccessfully, retryActivity); } @Override protected void doCatch(Throwable e) throws Throwable { retryActivity.set(true); } }; restartRunUnreliableActivityTillSuccess(retryActivity); } @Asynchronous private void setRetryActivityToFalse( Promise<Void> activityRanSuccessfully, @NoWait Settable<Boolean> retryActivity) { retryActivity.set(false); } @Asynchronous private void restartRunUnreliableActivityTillSuccess( Settable<Boolean> retryActivity) { if (retryActivity.get()) { runUnreliableActivityTillSuccess(); } } }

Der Workflow funktioniert folgendermaßen:

  1. runUnreliableActivityTillSuccess erstellt ein Settable<Boolean>-Objekt namens retryActivity, das verwendet wird, um anzugeben, ob die Aktivität fehlgeschlagen ist und erneut getestet werden sollte. Settable<T> ist von Promise<T> abgeleitet und funktioniert zwar ähnlich, jedoch legen Sie den Wert eines Settable<T>-Objekts manuell fest.

  2. runUnreliableActivityTillSuccess implementiert eine anonyme verschachtelte TryCatch-Klasse zur Verarbeitung von Ausnahmen, die von der unreliableActivity-Aktivität ausgegeben werden. Weitere Informationen zum Umgang mit Ausnahmen, die von asynchronem Code ausgegeben werden, finden Sie unter Fehlerbehandlung.

  3. doTry führt die unreliableActivity-Aktivität aus, die ein Promise<Void>-Objekt namens activityRanSuccessfully zurückgibt.

  4. doTry ruft die asynchrone setRetryActivityToFalse-Methode auf, die zwei Parameter umfasst:

    • activityRanSuccessfully übernimmt das Promise<Void>-Objekt, das von der unreliableActivity-Aktivität zurückgegeben wird.

    • retryActivity übernimmt das retryActivity-Objekt.

    Bei Abschluss von unreliableActivity wird activityRanSuccessfully einsatzbereit und setRetryActivityToFalse legt retryActivity auf "false" fest. Andernfalls wird activityRanSuccessfully nicht einsatzbereit und setRetryActivityToFalse wird nicht ausgeführt.

  5. Wenn unreliableActivity eine Ausnahme ausgibt, ruft das Framework doCatch auf und übergibt es an das Ausnahmeobjekt. doCatch legt retryActivity auf "true" fest.

  6. runUnreliableActivityTillSuccess ruft die asynchrone restartRunUnreliableActivityTillSuccess-Methode auf und übergibt ihr das retryActivity-Objekt. Da retryActivity ein Promise<T>-Typ ist, verschiebt restartRunUnreliableActivityTillSuccess die Ausführung, bis retryActivity einsatzbereit ist. Dies ist der Fall, sobald TryCatch abgeschlossen wird.

  7. Wenn retryActivity einsatzbereit ist, extrahiert restartRunUnreliableActivityTillSuccess den Wert.

    • Wenn der Wert false ist, war die Wiederholung erfolgreich. restartRunUnreliableActivityTillSuccess unternimmt nichts und die Wiederholungssequenz wird beendet.

    • Wenn als Wert "true" ausgegeben wird, ist der Wiederholungsversuch fehlgeschlagen. restartRunUnreliableActivityTillSuccess ruft runUnreliableActivityTillSuccess auf, um die Aktivität erneut auszuführen.

  8. Die Schritte 1 bis 7 werden wiederholt, bis unreliableActivity abgeschlossen wird.

Anmerkung

doCatch verarbeitet die Ausnahme nicht, sondern legt nur das retryActivity-Objekt auf "true" fest, um anzugeben, dass die Aktivität fehlgeschlagen ist. Die Wiederholung wird von der asynchronen restartRunUnreliableActivityTillSuccess-Methode verarbeitet, die die Ausführung verschiebt, bis TryCatch abgeschlossen wird. Der Grund für diesen Ansatz ist, dass Sie eine Aktivität, die Sie in doCatch wiederholen, nicht beenden können. Wenn die Aktivität in restartRunUnreliableActivityTillSuccess wiederholt wird, können Sie Aktivitäten ausführen, die sich beenden lassen.

Exponentielle Wiederholungsstrategie

Bei der exponentiellen Wiederholungsstrategie führt das Framework eine fehlgeschlagene Aktivität nach einem festgelegten Zeitraum (N Sekunden) erneut aus. Schlägt dieser Versuch fehl, wiederholt das Framework die Aktivität nach 2N Sekunden, dann nach 4N Sekunden usw. Da die Wartezeit sehr lang werden kann, werden Sie die Wiederholungen nicht endlos fortsetzen, sondern den Vorgang irgendwann beenden.

Das Framework bietet drei Möglichkeiten zur Implementierung einer exponentiellen Wiederholungsstrategie:

  • Die @ExponentialRetry-Anmerkung ist der einfachste Ansatz. Sie müssen die Wiederholungsoptionen jedoch bei der Kompilierung festlegen.

  • Die RetryDecorator-Klasse ermöglicht es Ihnen, die Wiederholungskonfiguration zur Laufzeit festzulegen und bei Bedarf zu ändern.

  • Die AsyncRetryingExecutor-Klasse ermöglicht es Ihnen, die Wiederholungskonfiguration zur Laufzeit festzulegen und bei Bedarf zu ändern. Darüber hinaus ruft das Framework eine vom Benutzer implementierte AsyncRunnable.run-Methode zur Ausführung jedes neuen Versuchs auf.

Alle Ansätze unterstützen folgende Konfigurationsoptionen, wobei die Werte für die Zeit in Sekunden angegeben werden:

  • Die erste Wiederholungswartezeit.

  • Den Backoff-Koeffizienten, der verwendet wird, um die Wiederholungsintervalle folgendermaßen zu errechnen:

    retryInterval = initialRetryIntervalSeconds * Math.pow(backoffCoefficient, numberOfTries - 2)

    Der Standardwert lautet 2.0.

  • Die maximale Anzahl an Wiederholungen. Der Standardwert ist unbegrenzt.

  • Das maximale Wiederholungsintervall. Der Standardwert ist unbegrenzt.

  • Die Ablaufzeit. Es werden keine Wiederholungen mehr ausgeführt, wenn die Gesamtdauer des Vorgangs diesen Wert übersteigt. Der Standardwert ist unbegrenzt.

  • Die Ausnahmen, die den Wiederholungsvorgang auslösen. Standardmäßig löst jede Ausnahme den Wiederholungsvorgang aus.

  • Die Ausnahmen, die keinen Wiederholungsvorgang auslösen. Standardmäßig sind keine Ausnahmen ausgeschlossen.

In den folgenden Abschnitten werden die verschiedenen Methoden zur Implementierung einer exponentiellen Wiederholungsstrategie beschrieben.

Exponentielle Wiederholung mit @ExponentialRetry

Die einfachste Möglichkeit zur Implementierung einer exponentiellen Wiederholungsstrategie für eine Aktivität ist die Anwendung einer @ExponentialRetry -Anmerkung auf die Aktivität in der Schnittstellendefinition. Schlägt die Aktivität fehl, verarbeitet das Framework den Wiederholungsvorgang automatisch basierend auf den festgelegten Optionen. Das grundlegende Muster ist:

  1. Wenden Sie @ExponentialRetry auf die entsprechenden Aktivitäten an und legen Sie die Wiederholungskonfiguration fest.

  2. Schlägt eine mit einer Anmerkung versehene Aktivität fehl, wiederholt das Framework die Aktivität automatisch basierend auf der durch die Anmerkungsargumente festgelegten Konfiguration.

Der ExponentialRetryAnnotationWorkflow-Workflow-Worker implementiert die exponentielle Wiederholungsstrategie durch Verwendung einer @ExponentialRetry-Anmerkung. Er verwendet eine unreliableActivity-Aktivität, deren Schnittstellendefinition wie folgt in ExponentialRetryAnnotationActivities implementiert wird:

@Activities(version = "1.0") @ActivityRegistrationOptions( defaultTaskScheduleToStartTimeoutSeconds = 30, defaultTaskStartToCloseTimeoutSeconds = 30) public interface ExponentialRetryAnnotationActivities { @ExponentialRetry( initialRetryIntervalSeconds = 5, maximumAttempts = 5, exceptionsToRetry = IllegalStateException.class) public void unreliableActivity(); }

Die @ExponentialRetry-Optionen legen folgende Strategie fest:

  • Nur wiederholen, wenn die Aktivität IllegalStateException ausgibt.

  • Eine erste Wartezeit von 5 Sekunden verwenden.

  • Nicht mehr als 5 Wiederholungen.

Die Workflow-Schnittstelle wird in RetryWorkflow implementiert und enthält die Methode process, die den Eintrittspunkt des Workflows darstellt. Der Workflow-Worker wird in ExponentialRetryAnnotationWorkflowImpl wie folgt implementiert:

public class ExponentialRetryAnnotationWorkflowImpl implements RetryWorkflow { public void process() { handleUnreliableActivity(); } public void handleUnreliableActivity() { client.unreliableActivity(); } }

Der Workflow funktioniert folgendermaßen:

  1. process führt die synchrone handleUnreliableActivity-Methode aus.

  2. handleUnreliableActivity führt die unreliableActivity-Aktivität aus.

Schlägt die Aktivität fehl, indem IllegalStateException ausgegeben wird, führt das Framework automatisch die in ExponentialRetryAnnotationActivities festgelegte Wiederholungsstrategie aus.

Exponentielle Wiederholung mit der RetryDecorator-Klasse

@ExponentialRetry ist benutzerfreundlich. Allerdings ist die Konfiguration statisch und wird bei der Kompilierung festgelegt, sodass das Framework bei jedem Fehler der Aktivität dieselbe Wiederholungsstrategie anwendet. Sie können eine flexiblere exponentielle Wiederholungsstrategie implementieren, indem Sie die RetryDecorator-Klasse verwenden, mit der Sie die Konfiguration zur Laufzeit festlegen und bei Bedarf ändern können. Das grundlegende Muster ist:

  1. Erzeugen und konfigurieren Sie ein ExponentialRetryPolicy-Objekt, das die Wiederholungskonfiguration festlegt.

  2. Erzeugen Sie ein RetryDecorator-Objekt und geben Sie das ExponentialRetryPolicy-Objekt aus Schritt 1 an den Konstruktor weiter.

  3. Wenden Sie das Decorator-Objekt auf die Aktivität an, indem Sie den Klassennamen des Aktivitäts-Clients auf die Ausstattungsmethode des RetryDecorator-Objekts übergeben.

  4. Führen Sie die Aktivität aus.

Schlägt die Aktivität fehl, wiederholt das Framework die Aktivität basierend auf der ExponentialRetryPolicy-Objektkonfiguration. Sie können die Wiederholungskonfiguration bei Bedarf ändern, indem Sie dieses Objekt anpassen.

Anmerkung

Die @ExponentialRetry-Anmerkung und die RetryDecorator-Klasse schließen sich gegenseitig aus. Sie können RetryDecorator nicht verwenden, um eine Wiederholungsrichtlinie, die von einer @ExponentialRetry-Anmerkung festgelegt wird, dynamisch zu überschreiben.

Die folgende Workflow-Implementierung zeigt, wie die RetryDecorator-Klasse verwendet wird, um eine exponentielle Wiederholungsstrategie zu implementieren. Sie verwendet eine unreliableActivity-Aktivität, die nicht über eine @ExponentialRetry-Anmerkung verfügt. Die Workflow-Schnittstelle wird in RetryWorkflow implementiert und enthält die Methode process, die den Eintrittspunkt des Workflows darstellt. Der Workflow-Worker wird in DecoratorRetryWorkflowImpl wie folgt implementiert:

public class DecoratorRetryWorkflowImpl implements RetryWorkflow { ... public void process() { long initialRetryIntervalSeconds = 5; int maximumAttempts = 5; ExponentialRetryPolicy retryPolicy = new ExponentialRetryPolicy( initialRetryIntervalSeconds).withMaximumAttempts(maximumAttempts); Decorator retryDecorator = new RetryDecorator(retryPolicy); client = retryDecorator.decorate(RetryActivitiesClient.class, client); handleUnreliableActivity(); } public void handleUnreliableActivity() { client.unreliableActivity(); } }

Der Workflow funktioniert folgendermaßen:

  1. process erzeugt und konfiguriert ein ExponentialRetryPolicy-Objekt folgendermaßen:

    • Das erste Wiederholungsintervall wird an den Konstruktor übergeben.

    • Aufrufen der withMaximumAttempts-Methode des Objekts, um die maximale Anzahl der Versuche auf 5 festzulegen. ExponentialRetryPolicy zeigt andere with-Objekte an, mit denen Sie andere Konfigurationsoptionen angeben können.

  2. process erzeugt ein RetryDecorator-Objekt namens retryDecorator und übergibt das ExponentialRetryPolicy-Objekt aus Schritt 1 an den Konstruktor.

  3. process wendet den Decorator auf die Aktivität an, indem es die retryDecorator.decorate-Methode aufruft und ihr den Klassennamen des Aktivitäts-Clients übergibt.

  4. handleUnreliableActivity führt die Aktivität aus.

Schlägt die Aktivität fehl, wiederholt das Framework sie basierend auf der in Schritt 1 festgelegten Konfiguration.

Anmerkung

Einige with-Methoden der ExponentialRetryPolicy-Klasse besitzen eine entsprechende set-Methode, die Sie jederzeit aufrufen können, um die entsprechende Konfigurationsoption anzupassen: setBackoffCoefficient, setMaximumAttempts, setMaximumRetryIntervalSeconds und setMaximumRetryExpirationIntervalSeconds.

Exponentielle Wiederholung mit der AsyncRetryingExecutor-Klasse

Die RetryDecorator-Klasse bietet mehr Flexibilität bei der Konfiguration des Wiederholungsvorgangs als @ExponentialRetry, allerdings führt das Framework dennoch automatisch die Wiederholungen basierend auf der aktuellen Konfiguration des ExponentialRetryPolicy-Objekts aus. Ein flexiblerer Ansatz ist die Verwendung der AsyncRetryingExecutor-Klasse. Sie haben nicht nur die Möglichkeit, den Wiederholungsvorgang zur Laufzeit zu konfigurieren, sondern das Framework ruft zudem eine vom Benutzer implementierte AsyncRunnable.run-Methode zur Ausführung jeder Wiederholung auf, statt die Aktivität einfach auszuführen.

Das grundlegende Muster ist:

  1. Erzeugen und konfigurieren Sie ein ExponentialRetryPolicy-Objekt, um die Wiederholungskonfiguration festzulegen.

  2. Erzeugen Sie ein AsyncRetryingExecutor-Objekt und übergeben Sie ihm das ExponentialRetryPolicy-Objekt und eine Instanz der Workflow-Uhr.

  3. Implementieren Sie eine anonyme verschachtelte TryCatch- oder TryCatchFinally-Klasse.

  4. Implementieren Sie eine anonyme AsyncRunnable-Klasse und überschreiben Sie die run-Methode, um den benutzerdefinierten Code zur Ausführung der Aktivität zu implementieren.

  5. Überschreiben Sie doTry, um die execute-Methode des AsyncRetryingExecutor-Objekts aufzurufen, und übergeben Sie ihr die AsyncRunnable-Klasse aus Schritt 4. Das AsyncRetryingExecutor-Objekt ruft AsyncRunnable.run auf, um die Aktivität auszuführen.

  6. Schlägt die Aktivität fehl, ruft das AsyncRetryingExecutor-Objekt in Einklang mit der Wiederholungsrichtlinie, die in Schritt 1 festgelegt wurde, die AsyncRunnable.run-Methode erneut auf.

Der folgende Workflow zeigt, wie die AsyncRetryingExecutor-Klasse verwendet wird, um eine exponentielle Wiederholungsstrategie zu implementieren. Er verwendet dieselbe unreliableActivity-Aktivität wie der zuvor behandelte DecoratorRetryWorkflow-Workflow. Die Workflow-Schnittstelle wird in RetryWorkflow implementiert und enthält die Methode process, die den Eintrittspunkt des Workflows darstellt. Der Workflow-Worker wird in AsyncExecutorRetryWorkflowImpl wie folgt implementiert:

public class AsyncExecutorRetryWorkflowImpl implements RetryWorkflow { private final RetryActivitiesClient client = new RetryActivitiesClientImpl(); private final DecisionContextProvider contextProvider = new DecisionContextProviderImpl(); private final WorkflowClock clock = contextProvider.getDecisionContext().getWorkflowClock(); public void process() { long initialRetryIntervalSeconds = 5; int maximumAttempts = 5; handleUnreliableActivity(initialRetryIntervalSeconds, maximumAttempts); } public void handleUnreliableActivity(long initialRetryIntervalSeconds, int maximumAttempts) { ExponentialRetryPolicy retryPolicy = new ExponentialRetryPolicy(initialRetryIntervalSeconds).withMaximumAttempts(maximumAttempts); final AsyncExecutor executor = new AsyncRetryingExecutor(retryPolicy, clock); new TryCatch() { @Override protected void doTry() throws Throwable { executor.execute(new AsyncRunnable() { @Override public void run() throws Throwable { client.unreliableActivity(); } }); } @Override protected void doCatch(Throwable e) throws Throwable { } }; } }

Der Workflow funktioniert folgendermaßen:

  1. process ruft die handleUnreliableActivity-Methode auf und übergibt ihr die Konfigurationseinstellungen.

  2. handleUnreliableActivity verwendet die Konfigurationseinstellungen aus Schritt 1, um das ExponentialRetryPolicy-Objekt retryPolicy zu erzeugen.

  3. handleUnreliableActivity erzeugt das AsyncRetryExecutor-Objekt executor und übergibt das ExponentialRetryPolicy-Objekt aus Schritt 2 und eine Instanz der Workflow-Uhr an den Konstruktor.

  4. handleUnreliableActivity implementiert eine anonyme verschachtelte TryCatch-Klasse und überschreibt die doTry- und doCatch-Methode, um die Wiederholungen auszuführen und mögliche Ausnahmen zu verarbeiten.

  5. doTry erzeugt eine anonyme AsyncRunnable-Klasse und überschreibt die run-Methode, um den benutzerdefinierten Code zur Ausführung von unreliableActivity zu implementieren. Der Einfachheit halber führt run nur die Aktivität aus, Sie können bei Bedarf jedoch komplexere Ansätze implementieren.

  6. doTry ruft executor.execute auf und übergibt es an das AsyncRunnable-Objekt. execute ruft die run-Methode des AsyncRunnable-Objekts auf, um die Aktivität auszuführen.

  7. Schlägt die Aktivität fehl, ruft der Executor erneut run auf, basierend auf der Konfiguration des retryPolicy-Objekts.

Weitere Informationen zur Verwendung der TryCatch-Klasse zur Fehlerbehandlung finden Sie unter AWS Flow Frameworkfür Java-Ausnahmen.

Benutzerdefinierte Wiederholungsstrategie

Der flexibelste Ansatz zur Wiederholung fehlgeschlagener Aktivitäten ist eine benutzerdefinierte Strategie, die rekursiv eine asynchrone Methode aufruft, die die einzelnen Wiederholungen ausführt – ähnlich der "Wiederholen bis zum Erfolg"-Strategie. Statt die Aktivität einfach erneut auszuführen, implementieren Sie jedoch eine benutzerdefinierte Logik, die entscheidet, ob und wie jede Wiederholung ausgeführt werden soll. Das grundlegende Muster ist:

  1. Erzeugen Sie ein Settable<T>-Statusobjekt, das verwendet wird, um anzugeben, ob die Aktivität fehlgeschlagen ist.

  2. Implementieren Sie eine verschachtelte TryCatch- oder TryCatchFinally-Klasse.

  3. doTry führt die Aktivität aus.

  4. Schlägt die Aktivität fehl, legt doCatch das Statusobjekt fest, um anzugeben, dass die Aktivität fehlgeschlagen ist.

  5. Rufen Sie eine asynchrone Fehlerbehandlungsmethode auf und übergeben Sie ihr das Statusobjekt. Die Methode verschiebt die Ausführung, bis TryCatch oder TryCatchFinally abgeschlossen wird.

  6. Die Fehlerbehandlungsmethode entscheidet, ob und wann die Aktivität wiederholt werden soll.

Der folgende Workflow zeigt, wie eine benutzerdefinierte Wiederholungsstrategie implementiert wird. Er verwendet dieselbe unreliableActivity-Aktivität wie der DecoratorRetryWorkflow- und AsyncExecutorRetryWorkflow-Workflow. Die Workflow-Schnittstelle wird in RetryWorkflow implementiert und enthält die Methode process, die den Eintrittspunkt des Workflows darstellt. Der Workflow-Worker wird in CustomLogicRetryWorkflowImpl wie folgt implementiert:

public class CustomLogicRetryWorkflowImpl implements RetryWorkflow { ... public void process() { callActivityWithRetry(); } @Asynchronous public void callActivityWithRetry() { final Settable<Throwable> failure = new Settable<Throwable>(); new TryCatchFinally() { protected void doTry() throws Throwable { client.unreliableActivity(); } protected void doCatch(Throwable e) { failure.set(e); } protected void doFinally() throws Throwable { if (!failure.isReady()) { failure.set(null); } } }; retryOnFailure(failure); } @Asynchronous private void retryOnFailure(Promise<Throwable> failureP) { Throwable failure = failureP.get(); if (failure != null && shouldRetry(failure)) { callActivityWithRetry(); } } protected Boolean shouldRetry(Throwable e) { //custom logic to decide to retry the activity or not return true; } }

Der Workflow funktioniert folgendermaßen:

  1. process ruft die asynchrone callActivityWithRetry-Methode auf.

  2. callActivityWithRetry erstellt ein Settable<Throwable>-Objekt namens "failure" (Fehler), mit dem angezeigt wird, dass die Aktivität fehlgeschlagen ist. Settable<T> ist von Promise<T> abgeleitet und funktioniert zwar ähnlich, jedoch legen Sie den Wert eines Settable<T>-Objekts manuell fest.

  3. callActivityWithRetry implementiert eine anonyme verschachtelte TryCatchFinally-Klasse zur Verarbeitung von Ausnahmen, die von unreliableActivity ausgegeben werden. Weitere Informationen zum Umgang mit Ausnahmen, die von asynchronem Code ausgegeben werden, finden Sie unter AWS Flow Frameworkfür Java-Ausnahmen.

  4. doTry führt unreliableActivity aus.

  5. Wenn unreliableActivity eine Ausnahme auslöst, ruft das Framework doCatch auf und übergibt sie an das Ausnahmeobjekt. doCatch legt failure auf das Ausnahmeobjekt fest, was anzeigt, dass die Aktivität fehlgeschlagen ist, und versetzt das Objekt in einen betriebsbereiten Zustand.

  6. doFinally überprüft, ob failure einsatzbereit ist, was nur der Fall ist, wenn failure von doCatch festgelegt wurde.

    • Wenn failure einsatzbereit ist, führt doFinally keine Aktion aus.

    • Wenn failure nicht einsatzbereit ist, wird die Aktivität abgeschlossen und doFinally legt "failure" auf null fest.

  7. callActivityWithRetry ruft die asynchrone retryOnFailure-Methode auf und übergibt ihr "failure". Da "failure" ein Settable<T>-Typ ist, verschiebt callActivityWithRetry die Ausführung, bis "failure" einsatzbereit ist. Dies ist der Fall, sobald TryCatchFinally abgeschlossen wird.

  8. retryOnFailure ruft den Wert von "failure" ab.

    • Wenn der Fehler auf Null gesetzt ist, war der Wiederholungsversuch erfolgreich. retryOnFailure unternimmt nichts, wodurch der Wiederholungsprozess beendet wird.

    • Wenn "failure" auf ein Ausnahmeobjekt festgelegt ist und shouldRetry "true" zurückgibt, ruft retryOnFailure callActivityWithRetry auf, um die Aktivität zu wiederholen.

      shouldRetry implementiert eine benutzerdefinierte Logik, um zu entscheiden, ob eine fehlgeschlagene Aktivität wiederholt werden soll. Der Einfachheit halber gibt shouldRetry immer true zurück und retryOnFailure führt die Aktivität sofort aus, Sie können bei Bedarf jedoch eine komplexere Logik implementieren.

  9. Schritte 2 bis 8 wiederholen bisunreliableActivityschließt ab odershouldRetrybeschließt, den Prozess zu stoppen.

Anmerkung

doCatch verarbeitet den Wiederholungsvorgang nicht, sondern legt nur "failure" fest, um anzugeben, dass die Aktivität fehlgeschlagen ist. Der Wiederholungsvorgang wird von der asynchronen retryOnFailure-Methode verarbeitet, die die Ausführung verschiebt, bis TryCatch abgeschlossen wird. Der Grund für diesen Ansatz ist, dass Sie eine Aktivität, die Sie in doCatch wiederholen, nicht beenden können. Wenn die Aktivität in retryOnFailure wiederholt wird, können Sie Aktivitäten ausführen, die sich beenden lassen.