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应用程序(通过使用蛋糕模式,通过显式传递,或使用其他依赖注入技术).