Реализация в микроядре АККА

Следуя примеру документации (2.1.4), у меня возникли проблемы с загруженным микроядром обработчиком сообщений, где класс расширения 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()
  }
}

Должна ли действительно быть фиктивная инстанциация или, делая это, я вызываю некоторый побочный эффект, приводящий к обработке сообщений?

Основываясь на коде, приведенном Томасом Лечертом в примере минимального удаленного актера Akka 2.1, я превратил серверную сторону в актера, размещенного на микроядре.

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")
}

1 ответ

Решение

Если код, который вы разместили, действительно точен, просто переместите экземпляр joe экземпляр в startup операция вместо в конструкторе для загрузочного класса:

def startup = {
  system.actorOf(Props[Joe], name = "joe")
}

Актер привязан к имени joe должен быть запущен, прежде чем кто-то сможет найти его по имени и отправить ему сообщения. По сути, это то же самое, что запускать его в конструкторе загрузочного класса, но я считаю, что соглашение требует выполнения всех действий в startup функция в отличие от тела загрузочного класса (и, следовательно, конструктор)

Другие вопросы по тегам