Быстрый запуск Finagle

У меня есть голый проект SBT, к которому я добавил "com.twitter" %% "finagle-http" % "6.33.0", Я слежу за руководством по быстрому старту для Twitter Finagle. Код, который я имею, является прямой копией-вставкой:

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 "?

Если я установил точку останова на " modification 1 и оцените resp.contentString используя текущее состояние, HTML для сайта возвращается по желанию.

Как я могу заставить это напечатать, в то время как программа работает нормально?

1 ответ

Решение

Подпись onSuccess метод в твиттере Future отличается от того, что на стандартной библиотеке Future-вместо этого:

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

У вас есть это:

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

Т.е. он возвращает новое будущее, которое возвращает то же значение, что и старое будущее, но также выполняет побочный эффект, а не просто выполняет побочный эффект. (Как примечание, на мой взгляд, это один из многих способов, которыми API будущего Twitter лучше, чем стандартная библиотека - я предпочитаю и тот факт, что тип возвращаемого аргумента функции Unit и что метод не).

В вашем случае происходит то, что потоки, которые Finagle использует для клиента, демонизированы, поэтому, если вы не ожидаете явного результата в будущем, нет никакой гарантии, что JVM не завершит работу до того, как это будущее будет удовлетворено. Изменение кода для ожидания результата будущего, возвращаемого onSuccess заставит все работать как положено.

Другие вопросы по тегам