2016-04-27 68 views
1

我寫了下面的代碼發送電子郵件爲非阻塞操作。 它不適用於多個請求。如何在play framework 2.5中編寫異步操作?

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

由於play.Promise在play.2.5(java)中已棄用。我以前的代碼不支持。所以請給我適當的解決方案,使我的行動非阻塞。

+0

提問的好方法:https://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/ – TheGameiswar

+0

可以請你解釋一下我的問題出了什麼問題。其實這是我的第一個問題堆棧溢出.. –

+1

如果你給了更多的細節,你可能會得到更多的關注。在別人的鞋子回答你自己的想法 – TheGameiswar

回答

2

如果函數EmailService.sendVerificationMail被阻塞,CompletableFuture只會使其在調用線程上非阻塞。實際上它仍然在其他線程上阻塞(可能是常見的ForkJoinPool)。

如果只有幾個電子郵件任務正在運行,這不是問題。但是如果有太多的電子郵件任務(比如說100或更多),他們會「控制」這個池。這會導致「Convoy效應」,其他任務必須等待更多的時間才能開始。這可能嚴重損害服務器性能。

如果您有很多併發電子郵件任務,則可以創建自己的池來處理它們,而不是使用公共池。線程池比fork join更好,因爲它不允許偷工作。

或者您可以找到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

+0

謝謝@HKTonyLee。我會盡力實現你的代碼。你可以告訴我幾個異步電子郵件API。? –

+0

嗨@HKTonuLee,上面的代碼也阻止了這個函數。當我嘗試下面的代碼時,它變成了非阻塞,但有時它不工作。 –

+0

嗨@HKTonuLee,上面的代碼也阻止了這個函數。當我嘗試下面的代碼時,它變成了非阻塞,但有時它不工作。公共結果sendEmail(){CompletableFuture.supplyAsync(() - > EmailService.sendVerificationMail(appUser,「您的帳戶的電子郵件驗證」))然後應用(我 - >好(「得到的結果:」+我)); return ok(); }這種方法工作正常我不明白上述兩者之間有什麼區別請幫助我謝謝 –

相關問題