#與Akka集成
akka使用Actor模型,提高抽象層次,並提供一個更好的平臺,建立正確的併發和可伸縮的應用程序。
對於容錯,它採用“讓崩潰模式,該模型已在電信業的巨大成功,主要用於建立自我修復 - 系統永不停止的應用程序。
Actor模型也爲分佈式傳輸和真正可擴展、可容錯應用的基礎提供了抽象。
1.應用程序Actor系統
akka2.0能夠在若干個被稱作Actor系統的容器上工作。Actor系統管理爲了運行它包含的Actors的配置資源。
一個Play應用定義了一個特殊的actor系統,用來讓應用使用。這個actor系統跟隨應用的生命週期,當應用程序重啓時,它會自動重啓。
Play並不反對你在Play應用中使用另外的actor系統。Play默認的actor系統僅僅是一個啓動幾個actor的便捷方式,而不需要設置你自己的actor系統。
同play.libs.Akka助手可以訪問默認的應用程序actor系統:
ActorRef myActor = Akka.system().actorOf(new Props(MyActor.class));
2.配置
默認的actor系統的配置從Play的配置文件中讀取。例如,在conf/application.con中加入如下幾行,可以配置應用程序actor系統的默認Dispatcher(轉發器)。
akka.default-dispatcher.core-pool-size-max = 64
akka.debug.receive = on
3.將Akka的Future轉換爲Play的Promise
當你與Akka進行異步交互的時候,我們會得到Future對象,你可以使用play.libs.Akka.asPromise()提供的轉換方法輕易地將它轉換爲Play的Promise。
import static akka.pattern.Patterns.ask;
import play.libs.Akka;
import play.mvc.Result;
import static play.mvc.Results.async;
import play.libs.F.Function;
public static Result index() {
return async(
Akka.asPromise(ask(myActor,"hello", 1000)).map(
new Function<Object,Result>() {
public Result apply(Object response) {
return ok(response.toString());
}
}
)
);
}
3.異步執行代碼塊
Akka的一個普通用例是當有一些併發執行的計算時,不需要actor的額外工具。
如果你發現你創建以一個Actor池的理由是爲了進行並行計算,那麼這裏有更加簡單快速的方式:
import static play.libs.Akka.future;
import play.libs.F.*;
import java.util.concurrent.Callable;
public static Result index() {
return async(
future(new Callable<Integer>() {
public Integer call() {
return longComputation();
}
}).map(new Function<Integer,Result>() {
public Result apply(Integer i) {
return ok("Got " + i);
}
})
);
}
4.一部任務調度
你可以調度發送消息給actors,並且執行任務(函數或者Runnable實例)。你會得到一個可撤銷的返回,你可以調用撤銷的回調來取消調度操作的執行。
舉個例子,沒30秒向testActor發送一個消息:
Akka.system().scheduler().schedule(
Duration.create(0, TimeUnit.MILLISECONDS),
Duration.create(30, TimeUnit.MINUTES)
testActor,
"tick"
)
另一個例子,從現在起10秒後執行一個代碼塊:
Akka.system().scheduler().scheduleOnce(
Duration.create(10, TimeUnit.SECONDS),
new Runnable() {
public void run() {
file.delete()
}
}
);