如何在play framework 2.5中编写异步动作?

时间:2016-04-27 05:04:35

标签: java asynchronous playframework

我编写了以下代码,将电子邮件作为非阻止操作发送。 它超过1个请求不起作用。

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

在play.2.5(java)中不推荐使用play.Promise。我以前的代码不支持。所以请给我正确的解决方案,使我的行动成为非阻塞。

2 个答案:

答案 0 :(得分:2)

如果函数EmailService.sendVerificationMail阻塞,CompletableFuture仅使其在调用线程上无阻塞。实际上它仍然在其他线程上阻塞(可能是常见的ForkJoinPool)。

如果只运行多个电子邮件任务,则这不是问题。但是如果有太多的电子邮件任务(比如说100或更多),他们将会主宰#34;游泳池。这导致"康宏效应"和其他任务必须等待更多的时间来开始。这可能严重损害服务器性能。

如果您有大量并发电子邮件任务,则可以创建自己的池来处理它们,而不是使用公共池。线程池优于fork join pool,因为它不允许工作窃取。

或者你可以找到EmailService的异步API,或者如果可能的话自己实现它们。

要回答另一个问题,现在Play 2.5使用CompletionStage作为默认承诺。如果您只使用CompletionStage,它应该可以使用。

这里有一些示例代码。请注意在返回类型中使用CompletionStage

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

有关详细信息,您可以查看Play网站上的Java Migration Guide

答案 1 :(得分:0)

import java.util.concurrent.CompletableFuture;

public static CompletableFuture<Result> asynchronousProcessTask() {
        final CompletableFuture<Boolean> promise = CompletableFuture
                .supplyAsync(() -> Locate365Util.doTask());
        return promise.thenApplyAsync(
                (final Boolean i) -> ok("The Result of promise" + promise));
    }

** doTask() method must return boolean value