I have a bare sbt project to which I have added "com.twitter" %% "finagle-http" % "6.33.0"
. I am following the quickstart guide for Twitter Finagle. The code I have is a direct copy-paste:
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
}
Without "modification 2
" I get no output at all. With that println
added, I get
needed this
GET success: Response("HTTP/1.1 Status(200)")
Process finished with exit code 0
modification 2
"?contentString
printed from "modification 1
"?If I set a breakpoint on "modification 1
", and evaluate resp.contentString
using the current state, the HTML for the website is returned as desired.
How can I get that to print while the program is running normally?
The signature of the onSuccess
method on Twitter's Future
is different from the one on the standard library's Future
—instead of this:
def onSuccess[U](pf: PartialFunction[T, U])(implicit executor: ExecutionContext): Unit
You have this:
def onSuccess(f: (A) ⇒ Unit): Future[A]
I.e. it returns a new future that returns the same value as the old future, but also performs a side effect, instead of just performing the side effect. (As a side note, in my view this is one of the many ways the Twitter future API is better than the standard library's—I prefer both the fact that the function argument's return type is Unit
and that the method's isn't).
What's happening in your case is that the threads Finagle is using for the client are daemonized, so if you don't explicitly await the result of a future, there's no guarantee that the JVM won't exit before that future is satisfied. Changing your code to await the result of the future returned by onSuccess
will make everything work as expected.