我有一个akka演员,我想在该演员中使用一个简单的服务。该服务应该使用the client side api's singleRequest方法从本地网络中获取内容。
我的演员:
package actor
import actor.WorkerActor._
import akka.actor.Actor
import service.HealthCheckService
import scala.concurrent.ExecutionContext
object WorkerActor {
case object HealthCheck
}
class WorkerActor extends Actor {
implicit val system = context.system
implicit val ec: ExecutionContext = context.system.dispatcher
val healthCheckService = new HealthCheckService()
override def receive: Receive = {
case HealthCheck => sender ! healthCheckService.execute()
}
}
这里我也创建了一个ActorSystem和一个ExecutionContext,以便我的服务可以使用它:
package service
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpRequest, HttpResponse}
import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Failure, Success}
class HealthCheckService(implicit ec: ExecutionContext, implicit val system: ActorSystem) {
def execute() = {
val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = "http://someRandom.url"))
and do something with the response....
}
}
如果我没有将executionContext传递给服务,我会收到错误:
[error] Cannot find an implicit ExecutionContext. You might pass
[error] an (implicit ec: ExecutionContext) parameter to your method
[error] or import scala.concurrent.ExecutionContext.Implicits.global.
如果我没有将一个actor系统传入服务,我就会收到错误:
[error] could not find implicit value for parameter system: akka.actor.ActorSystem
[error] val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = "http://someRandom.url"))
问题:
答案 0 :(得分:0)
Http.apply
签名是
def apply()(implicit system: ActorSystem): HttpExt
因此您需要隐式或明确地将ActorSystem
传递给它。
我没有在服务中看到任何需要ExecutionContext的内容,因此假设您通过Future
调用singleRequest
执行了某些操作。 Future
上的任何方法都需要执行上下文。
所以代码是正确的,但可以简化一点:
class WorkerActor extends Actor {
// you do not need to declare implicit val if you just need to pass it once
val healthCheckService = new HealthCheckService(context.system)
override def receive: Receive = {
case HealthCheck => sender ! healthCheckService.execute()
}
}
class HealthCheckService(implicit val system: ActorSystem) {
// dispatcher is already implicit so you need just import it, not declare another val
import system.dispatcher
def execute() = {
val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = "http://someRandom.url"))
and do something with the response....
}
}
此外,根据您的服务代码,我有一种印象,您将来会以某种方式进行操作,可能会添加等待(只要您的问题服务不需要ActorSystem
),而是使用akka和管道消息来自Future
的演员。可能(作为第一个问题的回答),您需要查看后来使用singleRequest
的演员与链接到您添加的akka-http的演员的示例。