Different request-timeouts

116 views
Skip to first unread message

daniel...@gmail.com

unread,
Mar 31, 2015, 7:27:43 AM3/31/15
to spray...@googlegroups.com
We are using Spray for building a REST-like web service which also supports file uploads.
As far as we understand the spray.can.server.request-timeout setting globally affects after which 
time, in which the application was not able to produce a response, the request will time out.
While this is no problem for our other endpoints the upload endpoint requires a large timeout setting
as we support files up to about 100MB.

It's probably not recommended to generally set the timeout to a couple of minutes but otherwise 
we're  currently unable to support the upload of bigger files.

Is there a possibility to have different timeout settings  or override the timeout configured via application configuration?
What are our options?

Best regards

Daniel

Mathias Doenitz

unread,
Mar 31, 2015, 7:34:01 AM3/31/15
to spray...@googlegroups.com
Daniel,

you can change the timeout for specific incoming *connection* by sending a `SetRequestTimeout` message to the spray-can layer.
This is probably good enough for your use case.

Check out this docs section for details:
http://spray.io/documentation/1.2.2/spray-can/http-server/#request-timeouts

Cheers,
Mathias

---
mat...@spray.io
http://spray.io
> --
> You received this message because you are subscribed to the Google Groups "spray.io User List" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to spray-user+...@googlegroups.com.
> Visit this group at http://groups.google.com/group/spray-user.
> To view this discussion on the web visit https://groups.google.com/d/msgid/spray-user/3e8dfd1e-cab7-41df-93e2-2f0f3f0f48cd%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

daniel...@gmail.com

unread,
Mar 31, 2015, 1:24:10 PM3/31/15
to spray...@googlegroups.com
Hi Mathias,

great, seems as the following is working

def setRequestTimeout(timeout: Duration) = mapRequestContext { ctx =>
  ctx
.responder ! spray.http.SetRequestTimeout(timeout)
  ctx
}

Thank you! 

Mathias Doenitz

unread,
Mar 31, 2015, 3:05:58 PM3/31/15
to spray...@googlegroups.com
Yes, that does it.

Note, however, that the change in request timeout applies to the whole *connection*, not just to the current request.
This means that, if the client reuses the connection for another request, this request will then also be under the long timeout.
If you want to avoid that you’d have to set the timeout explicitly for *every* request, not just the long ones.
Also, things become complicated if you enable pipelining (because several requests from one connection can be in-flight),
so it’s probably best to keep it disabled.

Cheers,
Mathias

---
mat...@spray.io
http://spray.io

> --
> You received this message because you are subscribed to the Google Groups "spray.io User List" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to spray-user+...@googlegroups.com.
> Visit this group at http://groups.google.com/group/spray-user.
> To view this discussion on the web visit https://groups.google.com/d/msgid/spray-user/3e52fb09-68df-449a-a6a6-2bcaf7db6f25%40googlegroups.com.

daniel...@gmail.com

unread,
Apr 1, 2015, 1:25:25 AM4/1/15
to spray...@googlegroups.com
Ok great. With the *connection* do you mean the underlying responder of the RequestContext?
If so, i don't understand how this could be reused by another request.
What are the cases where a connection will be reused. Is this somehow predictable?

Daniel

Mathias Doenitz

unread,
Apr 1, 2015, 3:54:50 AM4/1/15
to spray...@googlegroups.com
Daniel,

> With the *connection* do you mean the underlying responder of the RequestContext?

With connection I mean the underlying HTTP (TCP) connection.
The `responder` of the `RequestContext` is your channel to the actor managing this connection.

> If so, i don't understand how this could be reused by another request.

HTTP connections can be (and are) generally reused for potentially many requests as establishing a new TCP connection is a somewhat costly process.
Once a connection is established a client could use it for 100s or even 1000s of independent requests.

> What are the cases where a connection will be reused. Is this somehow predictable?

In most cases connections are reused if
- the client and the server both speak HTTP/1.1 (rather than HTTP/1.0)
- neither the client nor the server set a `Connection: close` header
- the client has more requests that it wants to send to this server

What you can do in order to prevent connection reuse is to explicitly set a `Connection: close` response header.
This will cause spray-can to actively close the connection after the response has been sent out thereby preventing connection reuse very effectively.
If this forcing the client to establish a new connection for the next request is not an issue for your application
then this might be a viable alternative to setting the request timeout for every request as indicated in my last message.

Cheers,
Mathias

---
mat...@spray.io
http://spray.io

> --
> You received this message because you are subscribed to the Google Groups "spray.io User List" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to spray-user+...@googlegroups.com.
> Visit this group at http://groups.google.com/group/spray-user.
> To view this discussion on the web visit https://groups.google.com/d/msgid/spray-user/2a400a31-97ce-4123-b246-b28464e93224%40googlegroups.com.

daniel...@gmail.com

unread,
Apr 1, 2015, 5:33:18 AM4/1/15
to spray...@googlegroups.com
Hi Mathias,

thanks for the clarification. Closing the connection works and should be fine in our case.

Daniel

Stanislav Palatnik

unread,
Jun 18, 2015, 5:13:41 PM6/18/15
to spray...@googlegroups.com
Is there a way to set this per connection with spray-servlet?

Mathias Doenitz

unread,
Jun 19, 2015, 8:53:03 AM6/19/15
to spray...@googlegroups.com
Unfortunately, no.
The servlet API doesn’t surface connection management at all,
so there is nothing that we can do to influence it, except from setting response headers.
If you set a `Connection: close` response header, then the servlet container should “do the right thing”.

Cheers,
Mathias

---
mat...@spray.io
http://spray.io

> --
> You received this message because you are subscribed to the Google Groups "spray.io User List" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to spray-user+...@googlegroups.com.
> Visit this group at http://groups.google.com/group/spray-user.
> To view this discussion on the web visit https://groups.google.com/d/msgid/spray-user/6220c5f4-418e-47fe-bf56-b0dea6cdf213%40googlegroups.com.

Jonathan Chow

unread,
Jun 24, 2015, 4:04:19 AM6/24/15
to spray...@googlegroups.com
Hi Mathias,

I have some routes that require a longer timeout. I'm using the same directive that Daniel described earlier in this thread. I tested the timeout is indeed set when the routes are running live.

However, when I unit test these routes, the RouteResult handler fails because it doesn't recognise the CommandWrapper message:

Do you have any suggestions for how to handle this case?

Cheers,

Jonathan
Reply all
Reply to author
Forward
0 new messages