2

I am going to use Dispatch to write a simple HTTP client. I call dispatch.Http to get a future and call the future to get the response

val request = ...
val future = Http(request) // call the server asynchronously
val response = future() // wait for the response from the server

Now I wonder how I can wait with timeout. I would like the last API call to be:

// throw an exception if no response received within timeout
val response = future(timeout: Long)

Does it make sense ?

I understand that Dispatch return scala.concurrent.Future, which does not provide API with timeout. How would you suggest me implement it ?

Urist McDev
  • 498
  • 3
  • 14
Michael
  • 41,026
  • 70
  • 193
  • 341

2 Answers2

5

You can create configured Http client:

val httpApplicationClient = Http.configure( _.setRequestTimeoutInMs(3000) )

val future = httpApplicationClient(request)

...

Hasselbach
  • 136
  • 2
  • 6
  • 1
    `_.setRequestTimeout(3000)` since Async HTTP Client 1.9. – Arkadi Shishlov Jan 25 '16 at 22:31
  • 1
    This can also be done per-request: `req.underlying(_.setRequestTimeout(3000))` – Carlos Ferreyra Jun 29 '16 at 19:11
  • When I first read this answer, I was unable to find the source of the author's information. After some digging, I found `dispatch`'s javadoc: https://static.javadoc.io/net.databinder.dispatch/dispatch-core_2.11/0.11.2/index.html#dispatch.Http@configure(withBuilder:com.ning.http.client.AsyncHttpClientConfig.Builder=>com.ning.http.client.AsyncHttpClientConfig.Builder):dispatch.Http and piece it together with `AsyncHttpClientConfig.Builder` https://asynchttpclient.github.io/async-http-client/apidocs/com/ning/http/client/AsyncHttpClientConfig.Builder.html – knight Dec 07 '16 at 15:14
3

First, you can use Await:

import scala.concurrent.Await
import scala.concurrent.duration._

Await.result(future, 10 seconds) //you can specify timeout here

The problem is that it will throw an exception if the future did not manage to return in specified timeout.

If you need more flexibility here is the second approach:

val futureTimeout = Promise.timeout("Timed out" /* or throw new RuntimeException("timed out") */, 10 seconds)
Future.firstCompletedOf(Seq(futureResult, futureTimeout)).map {
  case result: SomeType => //do something
  case timedOut: SomeOtherType => //handle timeout
}
serejja
  • 22,901
  • 6
  • 64
  • 72
  • Thanks you ! I forgot about `Await` ! – Michael Mar 18 '14 at 13:43
  • where from you got Promise.timeout ? I don't see it in API: http://www.scala-lang.org/files/archive/nightly/docs/library/index.html#scala.concurrent.Promise$ . – Waldemar Wosiński Sep 30 '15 at 12:56
  • Promise.timeout is specific of the Play framework. It seems this is the link for the documentation: https://www.playframework.com/documentation/2.1.x/api/java/play/libs/F.Promise.html – Ismael Oct 08 '15 at 18:55