How timeout works in Dispatch

392 views Asked by At

At API there is:

val http = Http.configure(_
    .setConnectionTimeoutInMs(1)
  )

What for is this config? I use it with:

.setMaxRequestRetry(0)

I fought I will get failed future after timeout. Future I create like that:

val f = http(u OK as.String)
  f.map {
    NotificationClientConnectionParams.parseFromString
  }

But instead of failure I get success long after my timeout. How it should work?

My test looks like this:

val startTime = java.time.LocalTime.now()
val f = TcpUtil2.registerClientViaDispatch(ClientHeaders("12345", "123456789"))
f onSuccess {
  case c =>
    println(s"Success: $c")
    println(java.time.Duration.between(startTime, java.time.LocalTime.now()).toMillis)
}
f onFailure {
  case e =>
    println(s"failure:${e.getMessage}")
}
Thread.sleep(2000)

Response time is in hundreds of milliseconds and I got success. Is it a bug of dispatch?

1

There are 1 answers

1
Ihor Kaharlichenko On

An HTTP roundtrip goes through several phases (overly simplified):

  1. establishing connection
  2. connection established
  3. sending request payload
  4. request payload sent
  5. waiting for response payload
  6. receiving response payload
  7. response payload received

From what I understand you measure the time between states 1 and 7.

setConnectionTimeoutInMs comes from async-http-client which is used by Dispatch internally. Here's an excerpt from its documentation:

Set the maximum time in millisecond an AsyncHttpClient can wait when connecting to a remote host

Thus, this method sets the maximum time the client will wait between states 1 and 2.

There's also setRequestTimeoutInMs:

Set the maximum time in millisecond an AsyncHttpClient wait for a response

This method seems to set the time between states 5 and 6 (or 7, I'm not sure which one).


So here's what's probably happening in your case. You connect to remote host, the server accepts the connection very quickly (the time between 1 and 2 is small), so your Future doesn't get failed. Then there are several options: either server takes a lot of time to prepare the response before it starts sending it back to you (the time between 5 and 6), or the response is very big so it takes a lot of time to deliver it to you (the time between 6 and 7), or both. But since you don't set the request timeout, your Future is not getting failed because of this.