I just created a local endpoint to take seconds whatever I set like this
http://localhost:4000/dev/timeout?seconds=60
This will just sleep for 60 seconds.
To test in iex console
client = Tesla.client([{Tesla.Middleware.Timeout, timeout: 15000}])
%Tesla.Client{
fun: nil,
pre: [{Tesla.Middleware.Timeout, :call, [[timeout: 15000]]}],
post: [],
adapter: nil
}
Tesla.get(client, "http://localhost:4000/dev/timeout?seconds=60")
After 10 seconds it return timeout errors
{:error, :timeout}
I expected it takes 15seconds. but it just takes 10 seconds to timeout.
But if set this in config.exs. It takes 15 seconds to the timeout error
config :tesla, adapter: {Tesla.Adapter.Hackney, [recv_timeout: 15_000]}
What am I missing?
1 Like
tl;dr Tesla.Middleware.Timeout, timeout: 15000
should work but due to unfortunate complexities you must also set recv_timeout
.
See this issue for more:
opened 02:11PM - 12 Jan 18 UTC
closed 04:09AM - 16 Feb 23 UTC
bug
workaround
hackney
In hackney version 1.3.1 they've reduced the default `recv_timeout` from infinit… y to 5s ([source](https://github.com/benoitc/hackney/blob/master/NEWS.md))
So, if you use `Tesla.Middleware.Timeout` with timeout bigger than 5s hackney will timeout regardless of your timeout.
A solution is to pass that `recv_timeout` to hackney's request method as [HTTPoison does](https://github.com/edgurgel/httpoison/blob/64c58d0683aeee3ed1b244893d8780960de99555/lib/httpoison/base.ex#L452)
There is no problem with the default `httpc` adapter as its default timeout is `infinity`
IIRC I ended up ditching the Timeout middleware completely for the reason you mentioned, also because that same middleware doesn’t work with Tesla.Mock
(I think that was the one?).