Scala spray-client定义了AKKA ActorRefFactory的含义

Ayu*_*lik 3 scala actor akka implicits spray

我正在尝试使用Scala和spray-client编写一个简单的HTTP客户端.我的客户基于Spray文档上给出的示例.

我的问题是该示例是创建一个新的隐式 ActorSystem即

implicit val system = ActorSystem()
Run Code Online (Sandbox Code Playgroud)

但我希望我的客户端可以重用,而不是创建一个新的ActorSystem.

这是我的代码的要点.

trait WebClient {
  def get(url: String)(implicit system: ActorSystem): Future[String]
}

object SprayWebClient extends WebClient {
  val pipeline: HttpRequest => Future[HttpResponse] = sendReceive

  def get(url: String): Future[String] = {
    val r = pipeline (Get("http://some.url/"))
    r.map(_.entity.asString)
  }

}
Run Code Online (Sandbox Code Playgroud)

但我得到两个关于implicits的编译器错误

implicit ActorRefFactory required: if outside of an Actor you need an implicit ActorSystem, inside of an actor this should be the implicit ActorContext WebClient.scala ...
Run Code Online (Sandbox Code Playgroud)

not enough arguments for method sendReceive: (implicit refFactory: akka.actor.ActorRefFactory, implicit executionContext: scala.concurrent.ExecutionContext, implicit futureTimeout: akka.util.Timeout)spray.http.HttpRequest => scala.concurrent.Future[spray.http.HttpResponse]. Unspecified value parameters refFactory, executionContext.   WebClient.scala...
Run Code Online (Sandbox Code Playgroud)

我该如何更改API定义?

jru*_*lph 10

这是一个解决方案:

import akka.actor.ActorSystem
import spray.http.{HttpRequest, HttpResponse}
import scala.concurrent.Future
import spray.client.pipelining._

trait WebClient {
  def get(url: String): Future[String]
}

class SprayWebClient(implicit system: ActorSystem) extends WebClient {
  import system.dispatcher

  val pipeline: HttpRequest => Future[HttpResponse] = sendReceive

  def get(url: String): Future[String] = {
    val r = pipeline (Get("http://some.url/"))
    r.map(_.entity.asString)
  }
}
Run Code Online (Sandbox Code Playgroud)

这是保持原始WebClient.get签名的另一个:

import akka.actor.ActorSystem
import spray.http.{HttpRequest, HttpResponse}
import scala.concurrent.Future
import spray.client.pipelining._

trait WebClient {
  def get(url: String)(implicit system: ActorSystem): Future[String]
}

object SprayWebClient extends WebClient {
  def get(url: String)(implicit system: ActorSystem): Future[String] = {
    import system.dispatcher

    val pipeline: HttpRequest => Future[HttpResponse] = sendReceive
    val r = pipeline (Get("http://some.url/"))
    r.map(_.entity.asString)
  }
}
Run Code Online (Sandbox Code Playgroud)

第二个是有点贵,因为管道是每次重新创建的,即使它理论上是静态的ActorSystem.我更喜欢第一个解决方案,并尝试找到一种方法来传播WebClient应用程序(通过使用蛋糕模式,通过显式传递,或使用其他依赖注入技术).