akka实现的actor
定义一个 Actor 类
要定义自己的Actor类,需要继承 Actor 并实现receive 方法.
receive 方法需要定义一系列 case 语句(类型为 PartialFunction[Any, Unit]) 来描述你的Actor能够处理哪些消息,以及如何进行处理。
如下例:
- import akka.actor.Actor
- import akka.actor.Props
- import akka.event.Logging
- class MyActor extends Actor {
- val log = Logging(context.system, this)
- def receive = {
- case "test" ⇒ log.info("received test")
- case _ ⇒ log.info("received unknown message")
- }
- }
需要提供一个接受的所有消息的模式匹配规则,如果你希望处理未知的消息,你需要象上例一样提供一个缺省的case分支。否则会有一个 akka.actor.UnhandledMessage(message, sender, recipient) 被发布到 Actor系统(ActorSystem)‘的 事件流(EventStream)中。
发送消息
向actor发送消息是使用下列方法之一。
- ! 意思是“fire-and-forget”, e.g. 异步发送一个消息并立即返回。也称为 tell.
- ? 异步发送一条消息并返回一个 Future代表一个可能的回应。也称为 ask.
每一个消息发送者分别保证自己的消息的次序.
Tell: Fire-forget
这是发送消息的推荐方式。 不会阻塞地等待消息。它拥有最好的并发性和可扩展性。
- actor ! "hello"
如果是在一个Actor中调用 ,那么发送方的actor引用会被隐式地作为消息的 sender: ActorRef 成员一起发送. 目的actor可以使用它来向原actor发送回应, 使用 sender ! replyMsg.
如果 不 是从Actor实例发送的, sender成员缺省为 deadLetters actor 引用。
Ask: Send-And-Receive-Future
ask 模式既包含actor也包含future, 所以它是作为一种使用模式,而不是ActorRef的方法:
- import akka.pattern.{ ask, pipe }
- case class Result(x: Int, s: String, d: Double)
- case object Request
- implicit val timeout = Timeout(5 seconds) // 下面的 `?` 会用到
- val f: Future[Result] =
- for {
- x ← ask(actorA, Request).mapTo[Int] // 直接调用
- s ← actorB ask Request mapTo manifest[String] // 隐式转换调用
- d ← actorC ? Request mapTo manifest[Double] // 通过符号名调用
- } yield Result(x, s, d)
- f pipeTo actorD // .. 或 ..
- pipe(f) to actorD
上面的例子展示了将 ask 与 future上的 pipeTo 模式一起使用,因为这是一种非常常用的组合。 请注意上面所有的调用都是完全非阻塞和异步的: ask 产生 Future, 三个Future通过for-语法组合成一个新的Future,然后用 pipeTo 在future上安装一个 onComplete-处理器来完成将收集到的 Result 发送到其它actor的动作。
使用 ask 将会象 tell 一样发送消息给接收方, 接收方必须通过 sender ! reply 发送回应来为返回的 Future 填充数据. ask 操作包括创建一个内部actor来处理回应,必须为这个内部actor指定一个超时期限,过了超时期限内部actor将被销毁以防止内存泄露。
如果要以异常来填充future你需要发送一个 Failure 消息给发送方。这个操作不会在actor处理消息发生异常时自动完成。
- try {
- val result = operation()
- sender ! result
- } catch {
- case e: Exception ⇒
- sender ! akka.actor.Status.Failure(e)
- throw e
- }
如果一个actor没有完成future, 它会在超时时限到来时过期, 以 AskTimeoutException来结束. 超时的时限是按下面的顺序和位置来获取的:
- 显式指定超时:
- import akka.util.duration._
- import akka.pattern.ask
- val future = myActor.ask("hello")(5 seconds)
- 提供类型为 akka.util.Timeout的隐式参数, 例如,
- import akka.util.duration._
- import akka.util.Timeout
- import akka.pattern.ask
- implicit val timeout = Timeout(5 seconds)
- val future = myActor ? "hello"
参阅 Futures (Scala) 了解更多关于等待和查询future的信息。
Future的onComplete, onResult, 或 onTimeout 方法可以用来注册一个回调,以便在Future完成时得到通知。从而提供一种避免阻塞的方法。
警告
在使用future回调如 onComplete, onSuccess, and onFailure时, 在actor内部你要小心避免捕捉该actor的引用, i.e. 不要在回调中调用该actor的方法或访问其可变状态。这会破坏actor的封装,会引用同步bug和race condition, 因为回调会与此actor一同被并发调度。 不幸的是目前还没有一种编译时的方法能够探测到这种非法访问。 参阅: Actor与共享可变状态
akka实现的actor的更多相关文章
- Akka系列(二):Akka中的Actor系统
前言......... Actor模型作为Akka中最核心的概念,所以Actor在Akka中的组织结构是至关重要,本文主要介绍Akka中Actor系统. 1.Actor系统 Actor作为一种封装状态 ...
- Akka简介与Actor模型
Akka是一个构建在JVM上,基于Actor模型的的并发框架,为构建伸缩性强,有弹性的响应式并发应用提高更好的平台.本文主要是个人对Akka的学习和应用中的一些理解. Actor模型 Akka的核心就 ...
- akka设计模式系列-actor锚定
actor锚定模式是指使用actorSelection对acor进行锚定的设计模式,也可以说是一个对actor的引用技巧.在某些情况下,我们可能需要能够根据Actor的path锚定对应的实例.简单来说 ...
- Akka简介与Actor模型(一)
前言...... Akka是一个构建在JVM上,基于Actor模型的的并发框架,为构建伸缩性强,有弹性的响应式并发应用提高更好的平台.本文主要是个人对Akka的学习和应用中的一些理解. Actor模型 ...
- [翻译]AKKA笔记 - ACTOR生命周期 - 基本 -5
原文地址:http://rerun.me/2014/10/21/akka-notes-actor-lifecycle-basic/ (请注意这了讨论的生命周期并不包括 preRestart 或者pos ...
- [Scala] akka actor编程(一)
Akka基础 Akka笔记之Actor简介 Akka中的Actor遵循Actor模型.你可以把Actor当作是人.这些人不会亲自去和别人交谈.他们只通过邮件来交流. 1. 消息传递 2. 并发 3 ...
- Akka(2):Actor生命周期管理 - 监控和监视
在开始讨论Akka中对Actor的生命周期管理前,我们先探讨一下所谓的Actor编程模式.对比起我们习惯的行令式(imperative)编程模式,Actor编程模式更接近现实中的应用场景和功能测试模式 ...
- Actor模型-Akka
英文原文链接,译文链接,原文作者:Arun Manivannan ,译者:有孚 写过多线程的人都不会否认,多线程应用的维护是件多么困难和痛苦的事.我说的是维护,这是因为开始的时候还很简单,一旦你看到性 ...
- Akka系列---什么是Actor
本文已.Net语法为主,同时写有Scala及Java实现代码 严肃的说,演员是一个广泛的概念,作为外行人我对Actor 模型的定义: Actor是一个系统中参与者的虚拟人物,Actor与Actor之间 ...
随机推荐
- 如何用python搞定验证码中的噪点
背景:朋友在为"关山口男子职业技术学校"写一款校园应用,于是找MoonXue写一个学生选课系统的登录接口.为了搞定这个接口,不得不先搞定这个系统的验证码. 验证码大概是这个样子 看 ...
- Fibonacci(斐波那契)非递归实现。容易看懂
#include<iostream>using namespace std;int main(){ int n; cout<<"please input a n\n& ...
- 更新证书错误:No matching provisioning profiles found
在Xcode中当你在更新了你得证书而再重新编译你的程序,真机调试会出现“Your build settings specify a provisioning profile with the UUID ...
- 安装 mbed os 开发环境yotta
feature: 采用Python编写, Pip 包管理 CMake, the build system that yotta usesa compiler, to actually compile ...
- CentOS 6.6编译安装Nginx1.6.2+MySQL5.6.21+PHP5.6.3
http://www.osyunwei.com/archives/8867.html 一.配置防火墙,开启80端口.3306端口 vi /etc/sysconfig/iptables #编辑防火墙配置 ...
- c语言-四阶龙格-库塔法
#include<stdio.h> #include<math.h> #define n 14 //double func1(double x, double y); doub ...
- 3、Android Intent Flag的介绍
介绍:http://blog.csdn.net/luckily01/article/details/7737499
- hosts持续更新
Google hosts网址: https://laod.cn/hosts/2016-google-hosts.html
- Git在Windows环境下配置Diff以及Merge工具---DiffMerge
参考出处:http://coding4streetcred.com/blog/post/Configure-DiffMerge-for-Your-Git-DiffTool主要转自:http://blo ...
- Why sql is called structured query language?1 - 12
SQL has much to do with a researcher at IBM, Edgar F. (Ted) Codd, an Oxford-trained mathematician, w ...