2016-04-27 9 views
1

Ich habe den folgenden Code geschrieben, um eine E-Mail als nicht blockierende Aktion zu senden. Es funktioniert nicht für mehr als 1 Anfrage.Wie schreibe ich asynchrone Aktionen in Play Framework 2.5?

CompletableFuture.supplyAsync(() -> 
EmailService.sendVerificationMail(appUser , mailString)). 
    thenApply(i -> ok("Got result: " + i)); 

play.Promise Wie in play.2.5 (Java) veraltet. Mein vorheriger Code unterstützt nicht. Also bitte geben Sie mir die richtige Lösung, um meine Aktion nicht blockierend zu machen.

+0

guter Weg, Frage zu stellen: https://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/ – TheGameiswar

+0

Können Sie bitte erklären, was falsch in meiner Frage ist. Eigentlich ist dies meine erste Frage auf Stack Überlauf. –

+1

Sie können mehr Aufmerksamkeit bekommen, wenn Sie mehr Details gaben. Denken Sie an andere Person Schuhe, die antwortet – TheGameiswar

Antwort

2

Wenn die Funktion EmailService.sendVerificationMail blockiert, macht CompletableFuture es nur auf dem aufrufenden Thread nicht blockierend. In der Tat blockiert es immer noch auf anderen Thread (wahrscheinlich die gemeinsame ForkJoinPool).

Dies ist kein Problem, wenn nur mehrere E-Mail-Aufgaben ausgeführt werden. Aber wenn es zu viele E-Mail-Aufgaben gibt (sagen wir 100 oder mehr), werden sie den Pool "dominieren". Dies verursacht "Convoy-Effekt" und andere Aufgaben müssen viel länger warten, um zu starten. Dies kann die Serverleistung stark beeinträchtigen.

Wenn Sie viele gleichzeitige E-Mail-Aufgaben haben, können Sie Ihren eigenen Pool erstellen, um sie zu behandeln, anstatt den gemeinsamen Pool zu verwenden. Der Thread-Pool ist besser als der Fork-Join-Pool, da er kein Work-Stealing zulässt.

Oder Sie finden die asynchronen APIs von , oder implementieren Sie sie nach Möglichkeit selbst. Um die andere Frage zu beantworten, verwendet Play 2.5 jetzt CompletionStage als Standardversprechen. Es sollte funktionieren, wenn Sie einfach CompletionStage verwenden.

Einige Beispielcode hier. Beachten Sie die Verwendung von CompletionStage im Rückgabetyp.

public CompletionStage<Result> testAction() { 
    return CompletableFuture 
      .supplyAsync(() -> EmailService.sendVerificationMail(appUser, mailString), EmailService.getExecutor()) 
      .thenApply(i -> ok("Got result: " + i)); 
} 

Für weitere Informationen können Sie die Java Migration Guide auf Spiel Website überprüfen.

+0

Danke @HKTonyLee. Ich werde versuchen, Ihren Code zu implementieren. Kannst du mir ein paar asynchrone E-Mail-APIs sagen? –

+0

Hii @HKTonuLee, oben Code blockiert auch die Funktion.Wenn ich mit unten Code versuchte es wurde nicht blockierend aber manchmal funktioniert es nicht. –

+0

Hii @HKTonuLee, oben Code blockiert auch die Funktion.Wenn ich mit unten Code versuchte es wurde nicht blockiert aber manchmal funktioniert es nicht. public Ergebnis sendEmail() {CompletableFuture.supplyAsync (() -> EmailService.sendVerificationMail (appUser, "E-Mail-Verifizierung für Ihr Konto")). thenApply (i -> ok ("Got result:" + i)); return ok(); } Diese Methode funktioniert gut Ich kann nicht verstehen, was der Unterschied zwischen zwei von oben ist Bitte helfen Sie mir Danke –

Verwandte Themen