【问题标题】:Failed on Injecting Akka Actor to Play Framework 2.5 with Guice使用 Guice 注入 Akka Actor 以播放 Framework 2.5 失败
【发布时间】:2016-05-12 06:16:29
【问题描述】:

我正在尝试在我的 Play 2.5 应用程序中使用 Akka 演员并进行依赖注入。我基本上关注了the documentation on that,下面是我的代码一瞥:

演员

基本上,我有一个简单的参与者,它接收一些数据,处理它,然后将其发送回调用者。

package actors    

import akka.actor._
import akka.pattern.{AskTimeoutException, ask}
import akka.util.Timeout
import javax.inject._

import com.google.inject.assistedinject.Assisted
import play.api.Configuration

import scala.concurrent.duration._
import scala.concurrent.ExecutionContext
import scala.concurrent.Future

object ServiceActor {
  val ConfigKey = "actors.path" // remote actor path

  trait Factory {
    def apply(key: String): Actor
  }
}

class ServiceActor @Inject()(configuration: Configuration,
                                   actorSystem: ActorSystem,
                                   @Assisted key: String)
                                  (implicit val ec: ExecutionContext)
  extends Actor {
  import ServiceActor._

  implicit val timeout = Timeout(5.minutes)

  def receive = {
    case data: SomeData => sender ! someFunction(data)
  }

  // implemented in the real code, omitted because not important for the question
  def someFunction = ??? 
}

模块

根据文档,我需要制作一个简单的模块并激活它。这是模块:

package modules

import com.google.inject.AbstractModule
import play.api.libs.concurrent.AkkaGuiceSupport

import actors.ServiceActor

class ServiceModule extends AbstractModule with AkkaGuiceSupport {
  def configure = {
    bindActor[ServiceActor]("service-actor")
  }
}

然后我通过将以下行添加到application.conf 来激活此模块:

play.modules {
  enabled += modules.ServiceModule
}

控制器

最后,我尝试在控制器中使用actor:

package controllers

import akka.actor._
import akka.pattern.ask
import akka.util.Timeout
import javax.inject._

import play.api.mvc._

import scala.concurrent.duration._
import scala.concurrent.ExecutionContext

@Singleton
class SearchController @Inject()(@Named("service-actor") serviceActor: ActorRef)
                                (implicit ec: ExecutionContext)
  extends Controller {

  implicit val timeout = Timeout(5.minutes)

  def search(param: String) = Action.async {

    val request = SomeRequestType(param)

    (serviceActor ? request).mapTo[SomeResponseType] map { result =>
      Ok(result.toString)
    }
  }
}

据我所知,我已经完美地遵循了文档,但是调用控制器给了我这个错误:

[AskTimeoutException: Recipient[Actor[akka://application/user/service-actor#-366470383]] 
had already been terminated. 
Sender[null] sent the message of type "some.namespace.SomeRequestType".]

据我所知,错误是关于演员是null,我们无法向它发送消息。虽然错误代码说“已经被终止”,但看起来演员从来没有被启动过。

由于我没有使用 Guice 的经验,我不知道先看哪里,我做错了什么。

问题是,我做错了什么?为什么actor没有启动,或者如果它确实已经终止,为什么它会被终止?我该如何解决这个问题?

非常感谢。

【问题讨论】:

  • 您的用例是否足够简单,可以消除 Guice 并只使用 javax.inject?

标签: scala dependency-injection akka playframework-2.5


【解决方案1】:

希望您已经解决了这个问题。但是我仍然在这里发布答案,仅供一些新人参考,因为我花了一段时间才弄清楚这个问题的原因。

据我了解,错误是关于演员如何为空,我们无法向其发送消息。

不完全是。问图案?有一个sender的隐式参数,默认为ActorRef.noSender,源码为here

通常,如果您在 Actor 内部,则在范围内有一个名为 self 的隐式 ActorRef,但由于您不在 Actor 中,它只是采用默认值。

虽然错误代码显示“已被终止”,但看起来演员从未被启动过。

正确。很可能您的演员一开始就没有正确启动。在您的控制台中,您应该会看到比 Play Webpage 响应中看到的更多错误消息。

例如,下面是我在收到 AskTimeoutException 之前实际遇到的错误。

1 error
akka.actor.ActorInitializationException: akka://application/user/user-actor: exception during creation
    at akka.actor.ActorInitializationException$.apply(Actor.scala:193)
    at akka.actor.ActorCell.create(ActorCell.scala:608)
    at akka.actor.ActorCell.invokeAll$1(ActorCell.scala:462)
    at akka.actor.ActorCell.systemInvoke(ActorCell.scala:484)
    at akka.dispatch.Mailbox.processAllSystemMessages(Mailbox.scala:282)
    at akka.dispatch.Mailbox.run(Mailbox.scala:223)
    at akka.dispatch.Mailbox.exec(Mailbox.scala:234)
    at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
Caused by: com.google.inject.ConfigurationException: Guice configuration errors:

最后,您可能需要再次检查 sbt 控制台以及您的注入,以确保首先启动了 actor。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-26
    • 1970-01-01
    • 2017-05-27
    • 1970-01-01
    • 2016-05-27
    • 2017-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多