理论教育 向Actor发送消息的方法和特点

向Actor发送消息的方法和特点

时间:2023-11-24 理论教育 版权反馈
【摘要】:向Actor发送消息时使用下列方法之一:1)!异步发送一条消息并返回一个Future代表一个可能的回应,也称为ask。每一个消息发送者分别保证自己消息的次序。如果要以异常来填充Future,需要发送一个Failure消息给发送方。这个操作不会在Actor处理消息发生异常时自动完成。

向Actor发送消息的方法和特点

向Actor发送消息时使用下列方法之一:

1)!意思是“fire-and-forget”,异步发送一个消息并立即返回,也称为tell。

2)?异步发送一条消息并返回一个Future代表一个可能的回应,也称为ask。每一个消息发送者分别保证自己消息的次序。

●tell:这是发送消息的推荐方式,不会阻塞等待消息,拥有最好的并发性和可扩展性。如果是在一个Actor中调用,那么发送方的Actor引用会被隐式地作为消息的sender:ActorRef成员一起发送,目的Actor可以用它向原Actor发送回应,使用sender!re⁃plyMsg。如果不是从Actor实例发送的,sender成员默认为deadLetters Actor的引用。

●ask:模式既包含Actor也包含Future,所以它是作为一种使用模式,而不是ActorRef的方法。

为了说明ask方法的使用,在例10-7中创建6个Actor,分别是MasterActor、TestAc⁃tor、ActorA、ActorB、ActorC、ActorD,在MasterActor中向TestActor发送“go”消息,TestActor接收并打印字符消息,并调用f函数,f函数中分别向ActorA、ActorB、ActorC发送Request消息,ActorA收到Request消息之后返回整数25,ActorB收到Request消息之后返回字符串“regan”,ActorC收到Request消息之后返回浮点类型7500.0。f函数中根据这些返回值通过yield关键字,产生新的Result对象并存在Future对象中,在TestActor中使用f函数返回的Future对象上的pipeTo方法,将消息转发到ActorD,ActorD中收到消息并打印出Result中的信息。下面是完整的示例代码。

【例10-7】ask方法调用示例。

978-7-111-54169-1-Chapter10-22.jpg

978-7-111-54169-1-Chapter10-23.jpg

978-7-111-54169-1-Chapter10-24.jpg

运行结果如图10-7所示。

978-7-111-54169-1-Chapter10-25.jpg(www.daowen.com)

图10-7 ask方法与Future的pipeTo模式使用

上面的例子展示了将ask与Future上的pipeTo模式一起使用,这是一种非常常用的组合。请注意上面所有的调用都是完全非阻塞和异步的,ask产生Future,3个Future通过for语法组合成一个新的Future,然后用pipeTo在Future上安装一个onComplete处理器来完成将收集到的Result发送到其他Actor的动作。

使用ask会像tell一样发送消息给接收方,接收方必须通过sender!reply发送回应来为返回的Future填充数据。ask操作包括创建一个内部Actor来处理回应,必须为这个内部Actor指定一个超时期限,过了超时期限,内部Actor将被销毁以防止内存泄露。如果要以异常来填充Future,需要发送一个Failure消息给发送方。这个操作不会在Actor处理消息发生异常时自动完成。例10-11展示了处理请求异常的情况。在try-catch语句块中,若发生了异常,将被case e:Exception匹配到,匹配到异常消息之后,通过sender的“!”方法,发送akka.actor.Status.Failuer(e)消息,并使用throw e将异常抛出。

【例10-8】try-catch语句块中处理请求异常示例。

978-7-111-54169-1-Chapter10-26.jpg

如果一个Actor没有完成Future,它会在超时时限到来时过期,以AskTimeoutException 来结束。超时的时限是按下面的顺序和位置来获取的:

●指定超时代码如下:

978-7-111-54169-1-Chapter10-27.jpg

●提供akka.util.Timeout的隐式参数代码如下:

978-7-111-54169-1-Chapter10-28.jpg

Future的onComplete、onResult或onTimeout方法可以用来注册一个回调,以便在Future完成时得到通知,从而提供一种避免阻塞的方法。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈