2017-04-06 1 views
2

Angenommen, ich habe eine Saga, die in wenigen Millisekunden Geld überträgt. Ich habe REST-Controller, der den Befehl aufruft, der die Saga auslöst. Wie kann ich auf das Ende der Saga warten, um die Ergebnisse oder Ausnahmen zu überprüfen, damit mein Controller als Antwort zurückkommt? Wenn es nur ein einziger Befehl wäre, der keine Saga auslöst, könnte ich ein Befehls-Gateway und einen Callback verwenden, der mich über Erfolg oder Misserfolg informiert.Gibt es eine Möglichkeit, auf die Ergebnisse oder Ausnahmen einer Saga zu warten?

UPDATE:

konnte ich mein Controller eine Antwort zurück haben, nachdem Saga endet:

1) Mein Controller-Methode gibt eine DeferredResult, die ich in einer Karte speichern

2) Mein Controller verfügt über einen Event-Handler, der auf ein Endereignis wartet, das DeferredResult aus der Map abruft und das Ergebnis setzt

Gibt es einen besseren Weg, dies zu tun?

Antwort

4

Axon wurde entwickelt, um verschiedene Komponenten zu entkoppeln. Einige Komponenten behandeln Befehle und erzeugen Ereignisse, andere konsumieren Ereignisse und aktualisieren ein Abfragemodell oder, im Falle eines Saga, erzeugen sie erneut Befehle.

Vorzugsweise sollten Benutzeroberflächen so konzipiert sein, dass sie auch auf diese "eventuell konsistente" Weise funktionieren. Beim Senden eines Befehls zeigt der Rückgabewert nur an, dass der Befehl erfolgreich verarbeitet wurde, nicht dass alle Nebenwirkungen ausgeführt wurden.

Der Grund ist einfach, wenn ein übertriebenes Beispiel verwendet wird: Was ist, wenn 100 Komponenten an einem Ereignis interessiert sind, das als Ergebnis eines Befehls erzeugt wird? Möchten Sie, dass der Befehlshandler blockiert, bis alle diese 100 Komponenten aktualisiert wurden? Dies würde zu einer dramatischen (technischen) Kopplung zwischen diesen Komponenten führen, was sich enorm auf die Skalierbarkeit auswirken würde.

Vor diesem Hintergrund möchten Sie wahrscheinlich immer noch eine Benutzeroberfläche basierend auf Änderungen in Lesemodellen aktualisieren. Wenn Sie erwarten, dass eine bestimmte Nebenwirkung in absehbarer Zeit eintritt, ist die Verwendung von DeferredResult oder CompletableFuture ein sehr eleganter Weg. Es ist im Grunde eine Art von Abfrage, wo Sie sagen: "Lass es mich wissen, wenn ...", im Gegensatz zu "Gib mir deinen aktuellen Zustand". Alternativ können Sie Aktualisierungen auch an die Benutzer in Echtzeit senden. Wir haben dies in mehreren Projekten auf Basis von Stomp (mit Spring Websockets) umgesetzt.

Vergessen Sie nicht, schließlich sauber latenten Ergebnisse aus Ihrer Karte, falls sie (siehe DeferredResult.onTimeout() abgelaufen haben. Es wäre schade, wenn Ihre Maschine wegen des übermäßigen Speicherverbrauch abgestürzt.

+0

Danke für den Einblick! – sofiaguyang

Verwandte Themen