tesla
tesla copied to clipboard
Mint adapter and :unknown messages
according to Mint's documentation (see https://hexdocs.pm/mint/Mint.HTTP.html#stream/2) Mint.HTTP.stream/2 (called here: https://github.com/teamon/tesla/blob/v1.3.2/lib/tesla/adapter/mint.ex#L316) will return :unknown if the message passed to it is not destined for the current connection. The documentation suggests to handle this like a normal message:
receive do
message ->
case Mint.HTTP.stream(conn, message) do
:unknown -> handle_normal_message(message)
{:ok, conn, responses} -> handle_responses(conn, responses)
end
end
long story short, this seems to indicate to me that messages that stream/2 labels as :unknown are not errors, just need to be handled differently (keep in mind: I am very much not an expert)
the Mint adapter on the other hand, converts these into errors (from https://github.com/teamon/tesla/blob/v1.3.2/lib/tesla/adapter/mint.ex#L307):
defp receive_packet(conn, ref, opts, acc \\ %{}) do
with {:ok, conn, responses} <- receive_message(conn, opts),
acc <- reduce_responses(responses, ref, acc) do
{:ok, conn, acc}
else
{:error, error} ->
if opts[:close_conn], do: {:ok, _conn} = close(conn)
{:error, error}
{:error, _conn, error, _res} ->
if opts[:close_conn], do: {:ok, _conn} = close(conn)
{:error, "Encounter Mint error #{inspect(error)}"}
:unknown ->
if opts[:close_conn], do: {:ok, _conn} = close(conn)
{:error, :unknown}
end
end
defp receive_message(conn, %{mode: :active} = opts) do
receive do
message ->
HTTP.stream(conn, message)
after
opts[:timeout] -> {:error, :timeout}
end
end
We do observer this behaviour from time to time (we get {:error, :unknown} responses), but I don't know how to reproduce it / write a failing test for it.
Last time i was getting this type of errors, these were messages from another process (as far as i remember messages like {:plug_conn, :sent}).
Error can be reproduced by sending any message to process, which is holding mint connection, while it's waiting for response messages.
Maybe for this type of errors would be more suitable to add logging, ignore this message and recall receive_packet function again.
@ericmj Could you give us a hand here?
I have opened an issue for a feature so that you can match on specific mint connection messages: https://github.com/elixir-mint/mint/issues/247.
IIRC tesla opens a single connection, sends a request, and closes the connection. If that's correct you can run in passive mode instead so you don't have to manage any messages: https://hexdocs.pm/mint/Mint.HTTP.html#module-mode.
Hello, what's the next for this issue of Mint adapter? Please correct me if any missing.
1, Currently, Mint adapter uses :active mode with one-off connection by default, do we need to change use :passive mode?
2, Do we still need to support :conn option to reuse the connection from outside, in this use case, looks like Mint adapter needs to take more boundary conditions, what do you think about it?
Thanks!
I think the next step would be to use :passive mode indeed.
The later one would be to implement active mode with real connection pooling
Also related to https://github.com/teamon/tesla/issues/301
I think we should move on with the passive mode for mint adapter, and direct people to use finch for persistent connections & pooling.
Any thoughts on that?
@teamon I think that's the right approach.