How to have ring requests timeout after X seconds?

602 Views Asked by At

Is there any way to make requests to my server automatically time out (on the server) after X seconds?

I want to do this because on heroku requests time out after 30 seconds, and I don't want to waste server resources on computing responses in these cases. I also want to kill any db transactions that are open, so I don't change the database without the user getting a decent response.

I'm using HTTP-kit 2.3.0 and compojure 1.6.1.

(I know that having requests take this long is not best practice but this is for a backoffice project, and these things happen for instance when the DB becomes unreachable)

1

There are 1 best solutions below

4
On

Killing DB transactions is not trivial. If the JDBC driver is trying to connect to a DB and is waiting for the DB server to respond, you can try to configure that timeout in the JDBC driver properties.

Otherwise you would have to try to kill a blocked thread in Java, which is not possible. You can try to interrupt it, but there's no guarantee that will interrupt all the way to the ring handler.

If you use the HTTPKit API directly (i.e. not using ring), you could send a response after a timeout (using core.async, for example). An example of that can be found here: https://www.braveclojure.com/core-async/

Support for async ring is in progress for HTTPKit https://github.com/http-kit/http-kit/issues/394 (The Ring 2 specification is WIP as well)

If you need a solution now, you could try Aleph instead. That gives you the convenience of Ring handlers, but also allows you to create a response asynchronously. https://github.com/ztellman/aleph

(there might be more alternatives. Vert.x comes to mind. Maybe other Clojure alternatives too)