Быстрый запуск 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
- Почему ответ не печатается без
modification 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
заставит все работать как положено.