Lv.8 非同期処理で行こう![play framework2.0] [java]

直接Resultを返す前にPromise(見込み)を返すことによって、非同期を実現している。
とりあえずPromiseを返しておいて、その間にResultを作っておくことで、
ノンブロッキングな機構になっている。

Promise<Result>の作り方

Promiseをつくる前に、もうひとつPromiseが必要になるみたい。
戻り値の型を定義するPromise。

[java toolbar=”false”]
Promise promiseOfPIValue
= computePIAsynchronously();
Promise promiseOfResult = promiseOfPIValue.map(
new Function() {
public Result apply(Double pi) {
return ok(“PI value computed: ” + pi);
}
}
);
[/java]

Play2.0だと、Webサービス(play.libs.WS)やAkka、play.libs.Akkaを使うと非同期処理として
扱われて、Promiseが返ってくるらしい。

(play.libs.Akkaを使ったサンプル)

[java toolbar=”false”]// 別スレッドで実行される
Promise promiseOfInt = Akka.future(
new Callable() {
public Integer call() {
intensiveComputation();
}
}
);
[/java]

これで実際にノンブロッキングなのか検証する方法が分からないけど、公式ドキュメントの
サンプルを多少直して動いたコード。
直した部分は、※1と※2の2か所。

[java toolbar=”false”]

import java.sql.Timestamp;
// 以下が非同期処理のために取り込んだもの
// importの選択肢が多かったので記載しとく
import play.libs.Akka;
import play.libs.F.Function;
import play.libs.F.Promise;
import java.util.concurrent.Callable;

public static Result index()
{
Promise promiseOfInt
= Akka.future(new Callable()
{
public Integer call()
{
Timestamp now
= new Timestamp(System.currentTimeMillis());
Timestamp after
= new Timestamp(System.currentTimeMillis() + 5000);
Logger.info(“intensive computing start!”);
// 5秒かかる処理
// ※1もともとはintensiveComputing()だった。
while (now.before(after))
{
now = new Timestamp(System.currentTimeMillis());
}
Logger.info(“intensive computing stop!”);
return 100;
}
});

// ※2 return をくわえた。
// 加えていいのか、わからないけど、加えないと
// コンパイルが通らなかったので、、、。
return async(promiseOfInt.map
(new Function()
{
public Result apply(Integer i)
{
Logger.info(“return the result asynchronously!!”);
return ok(“Got result: ” + i);
}
}));
}[/java]

アセスメント

  • playの非同期処理でResultの前に返すクラスが分かる
  • 非同期処理の実装方法が分かる

公式ドキュメントの、Handling asynchronous resultsを参照しました。