Finagle快速入门客户

时间:2016-02-06 09:04:14

标签: scala http finagle twitter-finagle

我有一个简单的sbt项目,我添加了"com.twitter" %% "finagle-http" % "6.33.0"。我正在关注Twitter Finagle的quickstart指南。我的代码是直接复制粘贴:

import com.twitter.finagle.{Http, Service}
import com.twitter.finagle.http
import com.twitter.util.{Await, Future}

object Client extends App {
  val client: Service[http.Request, http.Response] = Http.newService("www.scala-lang.org:80")
  val request = http.Request(http.Method.Get, "/")
  request.host = "www.scala-lang.org"
  val response: Future[http.Response] = client(request)
  response.onSuccess { resp: http.Response =>
    println("GET success: " + resp) 
    println(resp.contentString)    // modification 1
  }
  Await.ready(response)
  println("needed this")           // modification 2
}

没有“modification 2”我根本没有输出。添加println后,我得到了

needed this
GET success: Response("HTTP/1.1 Status(200)")

Process finished with exit code 0
  1. 为什么在没有“modification 2”的情况下打印回复?
  2. 为什么“contentString”中没有打印modification 1
  3. 如果我在“modification 1”上设置断点,并使用当前状态评估resp.contentString,则会根据需要返回网站的HTML。

    如何在程序正常运行时进行打印?

1 个答案:

答案 0 :(得分:8)

Twitter onSuccessFuture方法的签名与标准库Future上的签名不同 - 而不是:

def onSuccess[U](pf: PartialFunction[T, U])(implicit executor: ExecutionContext): Unit

你有这个:

def onSuccess(f: (A) ⇒ Unit): Future[A]

即。它返回一个新的未来,返回与旧的未来相同的值,但也执行副作用,而不是仅执行副作用。 (作为旁注,在我看来,这是Twitter未来API比标准库更好的多种方式之一 - 我更喜欢函数参数的返回类型为Unit并且方法是'n'的事实吨)。

在您的情况下发生的事情是Finagle用于客户端的线程是守护进程的,因此如果您没有明确等待未来的结果,则无法保证JVM在未来满足之前不会退出。更改代码以等待onSuccess返回的未来结果将使一切按预期工作。