问题描述
我们正在将我们的项目迁移到键入的akka演员。我们提供的服务可以随意创建演员,例如:
class Service(ac: ActorContext[_])
def action() = {
ac.spawn(MyBehavior().receive)
}
}
当我们尝试测试此服务时,就会出现问题。看来我们应该只使用testKit.spawn
或testKit.createTestProbe
方法。它可以很好地用于对我们的课程进行单元测试。
但是没有办法让ActorContext[_]
传递给正在测试的服务。
因此,似乎我们在服务中滥用了ActorContext。但是服务如何创建新的参与者呢?
我想传递一个特殊的ActorRef[CreateActor]
来创建那些演员。这样,我们可以删除ActorContext[_]
中对Service
的依赖,但是我想看看是否有更好的选择。
解决方法
首先,您不应该传递ActorContext
,因为在上下文中公开的许多方法都不是线程安全的。
您可以为每个JVM创建一个ActorSystem[SpawnProtocol.Command]
,并将其传递给您的服务。
然后您可以发送Spawn
命令,该命令将键入的actor行为发送给注入的actorSystem。
val echoActor: Future[ActorRef[Echo]] = actorSustem ? { replyTo: ActorRef[ActorRef[Echo]] => Spawn(echoBehavior,"echo-actor",Props.empty,replyTo)}
您是否真的需要从服务中创建参与者?
也许您可以进行顶层布线,在其中创建所有必需的参与者,然后向服务中注入ActorRef
。
当然,如果您的演员寿命短暂,并且根据需求被创建和销毁,那么我上面的建议是有道理的。