tesla icon indicating copy to clipboard operation
tesla copied to clipboard

Mint adapter and :unknown messages

Open jlgeering opened this issue 5 years ago • 7 comments

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.

jlgeering avatar Feb 17 '20 08:02 jlgeering

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.

alex-strizhakov avatar Feb 17 '20 09:02 alex-strizhakov

@ericmj Could you give us a hand here?

teamon avatar Mar 03 '20 09:03 teamon

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.

ericmj avatar Mar 03 '20 22:03 ericmj

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!

xinz avatar Apr 08 '20 06:04 xinz

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

teamon avatar Apr 16 '20 12:04 teamon

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 avatar Sep 10 '21 08:09 teamon

@teamon I think that's the right approach.

ericmj avatar Sep 10 '21 14:09 ericmj