我有一个类,它为客户端提供不同类型的Source
。当Source
运行时,应该产生一个actor,它将新的条目馈送到相应的流中。所以我的类需要能够产生actor。我知道两种方法来做到这一点:使用另一个演员的ActorContext
或使用ActorSystem
。是否有一个通用的抽象来生成新演员,以便我可以在我的类中注入一个助手,在需要时允许它生成演员,而不管它是如何完成的?
为此,我创建了一个ActorSpawner
接口,到目前为止,它运行得非常好:
trait ActorSpawner {
def spawn[T](behavior: Behavior[T]): ActorRef[T]
def spawn[T](behavior: Behavior[T], name: String): ActorRef[T]
}
但是,自从我升级到Akka 2.6后,我经常收到以下错误消息:
- 错误akka.actor.SupervisorStrategy -不支持从参与者[akka://...]外部访问ActorContext。参与者当前未处理任何消息,但从线程[...]调用了ActorContext *
在升级之前,这似乎不是一个问题,但现在我想知道我所做的是否是可取的,或者这是一种反模式。
2条答案
按热度按时间nuypyhwy1#
在Typed中,除了监护执行元(创建
ActorSystem
时创建的执行元)之外,执行元只能由其他执行元派生。仍然有很多情况下,在执行元外部执行的代码希望派生一个执行元。为此,您可以向执行元发送一条消息,并让该执行元派生具有所需行为的执行元。
如果您有一个唯一目的是产生其他参与者的参与者,Akka会包含
SpawnProtocol
,它与ask模式兼容:如果守护角色碰巧只在需要时产生其他角色,它可以实现
SpawnProtocol
,在这种情况下,ActorSystem
本身就是ActorRef[SpawnProtocol.Spawn]
,因此可以进一步简化为wz8daaqr2#
我知道有两种方法:使用另一个执行元的ActorContext或使用ActorSystem
我认为这对于Classic(即非类型化)Actor API是正确的,常见的抽象是
akka.actor.ActorRefFactory
,akka.actor.ActorSystem
和akka.actor.ActorContext
都对其进行了扩展。在新的类型化Actor API中,情况不再是这样了。你不能从
akka.actor.typed.ActorSystem
创建一个Actor,你只能从akka.actor.typed.scaladsl/javadsl.ActorContext
使用spawn*
家族的方法创建它,除了给定Actor系统的监护人/根Actor,你可以在Scala中通过ActorSystem(guardianBehavior: Behavior[T], name: String)
和朋友创建,或者在Java中使用ActorSystem.create(...)
等价物创建。ActorContext
只能从拥有它的参与者的消息处理线程或从setup
方法访问,并且生成错误日志的运行时检查自2.6.6
起就已到位。您可能从其他地方调用该对象。也许这篇文章在跟踪确切位置时会很有用:https://discuss.lightbend.com/t/akka-2-6-6-context-log-error-string-failed/6708/2