关于使用akka actor系统进行开发是一个普遍的问题。
我知道,它牺牲了静态类型检查以获得更大的灵活性,这不是问题。 Java一直都做同样的事情。
但我想至少动态检查ActorRef
的兼容性。我搜索了一些像actorRef.asInstanceOf[ActorType]
这样的方法。这种方法应该为通过消息传递的actorRef提供验证。它将允许安全的应用程序开发。但我发现没有办法进行任何类型的检查。甚至无法检查actorRef是否与给定的道具相对应。
此任务通常如何在akka应用程序中解决?是否有任何第三方动态检查工具?
答案 0 :(得分:2)
ActorRef
的目的是完全抽象收件人。向其发送消息绝对不能保证响应或甚至是发送消息的适合性。收件人可以删除邮件,路由邮件,存储邮件或处理邮件。任何关于处理和引起可能的响应消息的合同都完全是非正式的协议。
现在,在静态类型环境中放弃这听起来很多,但是它提供了一种编程模型,它带来了一系列优势,根据他们的设计要求您在假设消息的情况下发送和接收消息将被处理,但不知道何时何地将被处理。
关于如何通过配置和/发现在akka应用程序中解决此任务的方式。可接受消息的合同通常放在Protocol对象中,而这些Messages的有效接收者在创建时注入到调用Actor中,或者通过某些DiscoveryProtocol(本身隐藏在ActorRef后面)可以查询
我们假设您要查询UserRepository
,您可以创建如下协议:
case class User(id: Int, ... )
object UserRepositoryProtocol {
case class GetUser(userId: Int)
}
此外,我们假设未注入ActorRef
UserRepository
,但因为它只是众多服务之一,您的演员可能会使用通过一般的Discovery
服务发现:
object DiscoveryProtocol {
case class Discover(type: String)
case class Discovered(type: String, ref: ActorRef)
}
现在您可以获取这样的用户:
(discoveryRef ? Discover("UserRepository")).flatMap {
case Discovered("UserRepository",repository) =>
(repository ? GetUser(id)).map {
case user:User => // do something with the user
}
}
上述内容浓缩了发现并调用了ask
个操作链。您可能希望缓存已发现的引用,或者将检索到的用户交给其他正在进行工作的Actor,从而打破每个'?'在相同或不同的演员中成为!
和匹配的receive
。
最后一点说明了演员模型的力量。在传统的request => response
模型中,requestor
和response
的收件人必须凭借功能签名才能相同,但在演员模型中,您可以从一个演员发送,产生一个将处理响应的工人等。
答案 1 :(得分:0)
假设一个actor不仅封装在一个actor ref后面,而且一个actor的物理位置也是未知的。 actor可以在另一个物理服务器或VM上运行。你不能在另一个虚拟机的对象上调用instanceOf - 你怎么能期望得到一个演员的类呢?
现在,在建造时,我建议您考虑所有演员都是通过Akka的位置透明度远程。 (http://doc.akka.io/docs/akka/snapshot/general/remoting.html)如果你认为所有演员都很偏僻,那么你会突然想到你的设计会有所不同。将Akka视为分销工具包 - 这是它的主要好处!
如果你试图在运行时反映演员,那么你的设计可能有问题。相反,您需要知道演员可以接受和回应的消息。
如果你真的想知道一个演员能做什么和不能做什么,那么你可以考虑建模一些“接受”方法,其中一个演员将回复演员实现的所描述的API的当前版本示例 - 通过这种方式,您的客户端和服务器可以在运行时期间来回讨论动态支持的功能等。
我希望能为讨论做出贡献 - 只记得总是把演员视为在其他地方运行的东西,你会设计得恰当。这样做的好处是,如果您的用户群意外爆炸,您将能够以最小的努力扩展您的应用程序!