我编写了以下代码,将电子邮件作为非阻止操作发送。 它超过1个请求不起作用。
CompletableFuture.supplyAsync(() ->
EmailService.sendVerificationMail(appUser , mailString)).
thenApply(i -> ok("Got result: " + i));
在play.2.5(java)中不推荐使用play.Promise
。我以前的代码不支持。所以请给我正确的解决方案,使我的行动成为非阻塞。
答案 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