Вызов актера Акка из контроллера Play
Я играл с распределенным рабочим шаблоном, и я столкнулся с проблемой, выдвигающей работу из веб-запроса.
У примера проекта есть интерфейс:
val mediator = DistributedPubSubExtension(context.system).mediator
def receive = {
case work =>
log.info("Frontend received: " + work.toString())
implicit val timeout = Timeout(5.seconds)
(mediator ? Send("/user/master/active", work, localAffinity = false)) map {
case Master.Ack(_) => Ok
} recover { case _ => NotOk } pipeTo sender
}
И WorkProducer:
override def preStart(): Unit =
scheduler.scheduleOnce(5.seconds, self, Tick)
def receive = {
case Tick =>
n += 1
log.info("Produced work: {}", n)
val work = Work(nextWorkId(), n)
frontend ! work
context.become(waitAccepted(work), discardOld = false)
}
Все это прекрасно работает, когда я отправляю напрямую на внешний интерфейс с моего контроллера Play Framework:
def multiply(num: Long) = Action {
implicit request =>
implicit val timeout = Timeout(5.seconds)
val frontend = core.Main.frontend
frontend ! num
Ok
}
Сообщение, кажется, теряется. Интерфейс получает сообщение, но, похоже, что актеры вниз по течению этого не делают.
Я изменил конфигурацию воспроизведения, чтобы использовать ClusterActorRefProvider
play {
akka {
extensions = ["akka.contrib.pattern.ClusterReceptionistExtension"]
actor.provider = "akka.cluster.ClusterActorRefProvider"
remote.netty.tcp.port=0
}
}
Но безрезультатно.
1 ответ
Решение
Я был маппетом и не отправил правильное сообщение, контроллер должен выглядеть так:
def multiply(num: Long) = Action {
implicit request =>
implicit val timeout = Timeout(5.seconds)
val frontend = core.Main.frontend
val work = Work(nextWorkId(), num)
frontend ! work
Ok
}