如何动态检查演员的类型
How to dynamically check type of an actor
这是一个关于使用akka actor系统开发的一般问题。
我知道,它牺牲了静态类型检查以获得更大的灵活性,这不是问题所在。 Java一路做同样的事情
但我想至少动态检查 ActorRef
的兼容性。我搜索了一些方法,比如 actorRef.asInstanceOf[ActorType]
。这种方法应该为通过消息传递的 actorRef 提供验证。它将允许安全的应用程序开发。但是我找不到进行任何类型检查的方法。甚至不可能检查 actorRef 是否对应于给定的 Props。
这个任务在 akka 应用程序中通常是如何解决的?有没有第三方动态检测工具?
ActorRef
的目的是完全抽象收件人。向它发送消息绝对不能保证所发送消息的响应甚至适用性。收件人可以丢弃消息、路由消息、存储消息或处理消息。任何关于处理和导致发出可能的响应消息的合同完全是非正式协议。
现在,在静态类型的环境中,这听起来像是要放弃很多东西,但它提供了一种编程模型,它带来了自己的一系列优势,根据他们的设计,您在发送和接收消息时假设消息将被处理,但不知道它们将在何时何地被处理。
关于在 akka 应用程序中通常如何解决此任务是通过配置 and/discovery。可接受消息的契约通常放在协议对象中,而这些消息的有效接收者要么在创建时注入到调用 Actor 中,要么通过某些 DiscoveryProtocol(本身隐藏在 ActorRef 后面)进行查询
假设您有一个 UserRepository
想要查询,您将创建这样的协议:
case class User(id: Int, ... )
object UserRepositoryProtocol {
case class GetUser(userId: Int)
}
此外,我们假设 UserRepository
的 ActorRef
没有被注入,但因为它只是您的演员可能使用的许多 服务 之一通过一般 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
操作。您可能希望缓存发现的 ref 和/或将检索到的用户交给其他正在做这项工作的 Actor,打破每个 '?'在相同或不同的演员中进入 !
和匹配的 receive
。
最后一点说明了演员模型的力量。在传统的 request => response
模型中,requestor
和 response
的接收者必须是相同的,仅凭函数签名,但在演员模型中,您可以从一个演员发送, 产生一个 worker 来处理响应等
假设演员不仅被封装在演员引用后面,而且演员的物理位置也是未知的。参与者可以 运行 在另一台物理服务器或 VM 上。您不能在另一个 VM 中的对象上调用 instanceOf - 那么您怎么能期望获得演员的 class?
现在,在构建时,我建议您通过 Akka 的位置透明性考虑所有参与者都是远程的。 (http://doc.akka.io/docs/akka/snapshot/general/remoting.html) 如果您假设所有参与者都是远程的,突然之间您对您的设计的看法会有所不同。将 Akka 视为一个分发工具包——这是它的主要好处!
如果您试图在运行时反映演员,那么您的设计可能有问题。相反,您需要知道参与者可以接受和响应哪些消息。
如果你真的想知道演员能做什么和不能做什么,那么你可以考虑对某种 "Accepts" 方法进行建模,演员会用所描述的当前版本回复 API 例如,actor 实现的 - 通过这种方式,您的客户端和服务器可以来回讨论在运行时动态支持哪些功能等。
我希望这对讨论有所贡献 - 请记住始终将演员视为 运行 其他地方的东西,您将进行适当的设计。这样做的好处是,如果您的用户群意外激增,您将能够以非常小的努力扩展您的应用程序!
这是一个关于使用akka actor系统开发的一般问题。
我知道,它牺牲了静态类型检查以获得更大的灵活性,这不是问题所在。 Java一路做同样的事情
但我想至少动态检查 ActorRef
的兼容性。我搜索了一些方法,比如 actorRef.asInstanceOf[ActorType]
。这种方法应该为通过消息传递的 actorRef 提供验证。它将允许安全的应用程序开发。但是我找不到进行任何类型检查的方法。甚至不可能检查 actorRef 是否对应于给定的 Props。
这个任务在 akka 应用程序中通常是如何解决的?有没有第三方动态检测工具?
ActorRef
的目的是完全抽象收件人。向它发送消息绝对不能保证所发送消息的响应甚至适用性。收件人可以丢弃消息、路由消息、存储消息或处理消息。任何关于处理和导致发出可能的响应消息的合同完全是非正式协议。
现在,在静态类型的环境中,这听起来像是要放弃很多东西,但它提供了一种编程模型,它带来了自己的一系列优势,根据他们的设计,您在发送和接收消息时假设消息将被处理,但不知道它们将在何时何地被处理。
关于在 akka 应用程序中通常如何解决此任务是通过配置 and/discovery。可接受消息的契约通常放在协议对象中,而这些消息的有效接收者要么在创建时注入到调用 Actor 中,要么通过某些 DiscoveryProtocol(本身隐藏在 ActorRef 后面)进行查询
假设您有一个 UserRepository
想要查询,您将创建这样的协议:
case class User(id: Int, ... )
object UserRepositoryProtocol {
case class GetUser(userId: Int)
}
此外,我们假设 UserRepository
的 ActorRef
没有被注入,但因为它只是您的演员可能使用的许多 服务 之一通过一般 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
操作。您可能希望缓存发现的 ref 和/或将检索到的用户交给其他正在做这项工作的 Actor,打破每个 '?'在相同或不同的演员中进入 !
和匹配的 receive
。
最后一点说明了演员模型的力量。在传统的 request => response
模型中,requestor
和 response
的接收者必须是相同的,仅凭函数签名,但在演员模型中,您可以从一个演员发送, 产生一个 worker 来处理响应等
假设演员不仅被封装在演员引用后面,而且演员的物理位置也是未知的。参与者可以 运行 在另一台物理服务器或 VM 上。您不能在另一个 VM 中的对象上调用 instanceOf - 那么您怎么能期望获得演员的 class?
现在,在构建时,我建议您通过 Akka 的位置透明性考虑所有参与者都是远程的。 (http://doc.akka.io/docs/akka/snapshot/general/remoting.html) 如果您假设所有参与者都是远程的,突然之间您对您的设计的看法会有所不同。将 Akka 视为一个分发工具包——这是它的主要好处!
如果您试图在运行时反映演员,那么您的设计可能有问题。相反,您需要知道参与者可以接受和响应哪些消息。
如果你真的想知道演员能做什么和不能做什么,那么你可以考虑对某种 "Accepts" 方法进行建模,演员会用所描述的当前版本回复 API 例如,actor 实现的 - 通过这种方式,您的客户端和服务器可以来回讨论在运行时动态支持哪些功能等。
我希望这对讨论有所贡献 - 请记住始终将演员视为 运行 其他地方的东西,您将进行适当的设计。这样做的好处是,如果您的用户群意外激增,您将能够以非常小的努力扩展您的应用程序!