7

I've been using the Databinder Dispatch library in a client for a simple REST-ish API. I know how to detect if I get an HTTP response with an error status:

Http x (request) {
    case (200, _, _, content) => successResult(content())
    case (404, _, _, _) => notFoundErrorResult
    case (_, _, _, _) => genericErrorResult
}

But how can I distinguish an error response from a failure to get any response at all, because of an invalid domain or failure to connect? And is there any way to implement a timeout while still using synchronous semantics? If there's anything relevant in the API, I've missed it.

Urist McDev
  • 498
  • 3
  • 14
Eli Bishop
  • 216
  • 3
  • 6

3 Answers3

15

There is also a more elegant way to configure client using Http.configure method which receives Builder => Builder function as an argument:

val http = Http.configure(_.setAllowPoolingConnection(true).setConnectionTimeoutInMs(5000))
vlprans
  • 473
  • 6
  • 8
  • One might want to use setRequestTimeoutInMs in addition to setConnectionTimeoutInMs, as they complement each other nicely. – h7r Mar 22 '15 at 12:15
4

The Periodic Table tells us that >! sets up an exception listener and a recent mailing list thread explains how to set a timeout.

All together, then, you might do something like:

val http = new dispatch.Http {
  import org.apache.http.params.CoreConnectionPNames
  client.getParams.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 2000)
  client.getParams.setParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
}
http(req >! {
  case e => // ...
})

Note that I haven't tested this...

pr1001
  • 21,727
  • 17
  • 79
  • 125
  • Thanks... but I don't think the ExceptionListener does what I want. I want to make the HTTP request return some value X if it got exception E. It looks like ExceptionListener doesn't return anything - it's defined as Catcher[Unit]. It just gets called and then Http rethrows the exception. So I think I need to do a try/catch after all, which is what I wanted to avoid. – Eli Bishop Mar 13 '12 at 18:29
3

In case you are using Dispatch reboot (with AsyncHttpClient as the underlying library) this is how you'd set the client configuration:

val myHttp = new dispatch.Http {
  import com.ning.http.client._
  val builder = new AsyncHttpClientConfig.Builder()
  builder.setCompressionEnabled(true)
    .setAllowPoolingConnection(true)
    .setRequestTimeoutInMs(5000)
  override lazy val client = new AsyncHttpClient(builder.build())
}

and then just use this new object as you'd otherwise use http:

myHttp((url(baseUrl) <<? args) OK as.xml.Elem).either
thesamet
  • 6,382
  • 2
  • 31
  • 42
  • max connection pool size also needs to be defined here and how to define the dynamic queue size and max queue size ? – akshaymani Oct 12 '16 at 09:16