Play framework 2.0 -集成AKKA

#与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()
	    }
	  }
	);
 

相关推荐