按照文档示例(2.1.4),我在使用Microkernel加载的actor处理消息时遇到问题,其中Bootable扩展类的定义如下:
class HelloKernel extends Bootable {
val system = ActorSystem("hellokernel")
def startup = {
system.actorOf(Props[HelloActor]) ! Start
}
def shutdown = {
system.shutdown()
}
}
如果创建了一个虚拟(即未在代码中的其他位置使用)实例,如下所示,则会按预期处理消息。
class HelloKernel extends Bootable {
val system = ActorSystem("hellokernel")
val dummyActor = system.actorOf(Props[HelloActor])
def startup = {
system.actorOf(Props[HelloActor]) ! Start
}
def shutdown = {
system.shutdown()
}
}
是否确实存在虚拟实例化,或者通过这样做,我是否会产生一些副作用,导致消息被处理?
基于Thomas Letschert在Akka 2.1 minimal remote actor example中提供的代码,我已将服务器端转变为Microkernel托管的演员。
import akka.actor.Actor
import akka.actor.ActorLogging
import akka.actor.ActorSystem
import akka.actor.Props
import akka.kernel.Bootable
class Joe extends Actor {
def receive = {
case msg: String => println("joe received " + msg + " from " + sender)
case _ => println("Received unknown msg ")
}
}
class GreetServerKernel extends Bootable {
val system = ActorSystem("GreetingSystem")
val joe = system.actorOf(Props[Joe], name = "joe")
println(joe.path)
joe ! "local msg!"
println("Server ready")
def startup = {
}
def shutdown = {
println("PrimeWorker: Shutting Down")
system.shutdown
}
}
在这种情况下,虚拟实例化(当未删除消息时)是
val joe = system.actorOf(Props[Joe], name = "joe")
来电者代码是
import akka.actor._
import akka.actor.ActorDSL._
object GreetSender extends App {
implicit val system = ActorSystem("GreetingSystem")
val joe = system.actorFor("akka://GreetingSystem@127.0.0.1:2554/user/joe")
println(joe.path)
val a = actor(new Act {
whenStarting { joe ! "Hello Joe from remote" }
})
joe ! "Hello"
println("Client has sent Hello to joe")
}
答案 0 :(得分:1)
如果您发布的代码确实准确,那么只需将joe
实例的实例移动到startup
操作中,而不是在可引导类的构造函数中:
def startup = {
system.actorOf(Props[Joe], name = "joe")
}
绑定到名称joe
的actor需要先启动,然后才能按名称查找并向其发送消息。它与在可引导类的构造函数中启动它基本相同,但我相信约定要求在startup
函数中执行所有actor实例化,而不是可引导类体(因此构造函数)< / p>