Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,12 @@ if Code.ensure_loaded?(Mint.HTTP) do
clean_state = State.update_request_stream_queue(%{new_state | requests: %{}}, :queue.new())

if clean_state.retry > 0 do
attempt_reconnect(clean_state)
# A failed attempt already scheduled the next retry; ignore duplicate close events.
if clean_state.retry_attempt > 0 do
{:noreply, clean_state}
else
attempt_reconnect(clean_state)
end
else
send(clean_state.parent, {:elixir_grpc, :connection_down, self()})
{:stop, :normal, clean_state}
Expand Down
29 changes: 29 additions & 0 deletions grpc/test/grpc/adapters/mint/connection_process_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,35 @@ defmodule GRPC.Client.Adapters.Mint.ConnectionProcessTest do
end
end

describe "handle_info - duplicate connection close notifications" do
@describetag private_endpoint: ReconnectUnavailableEndpoint
setup :start_private_endpoint
setup :valid_connection_with_retry

test "does not start another retry chain after GOAWAY and tcp_closed", %{
process_pid: pid
} do
wait_until_open(pid)
state = :sys.get_state(pid)
:ok = GRPC.Server.stop_endpoint(ReconnectUnavailableEndpoint)

goaway_frame = <<8::24, 0x07, 0, 0::32, 0::32, 0::32>>
goaway = {:tcp, state.conn.socket, goaway_frame}
closed = {:tcp_closed, state.conn.socket}
unavailable_state = %{state | retry_timeout_ms: 60_000}

assert {:noreply, retrying_state} =
ConnectionProcess.handle_info(goaway, unavailable_state)

assert retrying_state.retry_attempt == 1

assert {:noreply, still_retrying_state} =
ConnectionProcess.handle_info(closed, retrying_state)

assert still_retrying_state.retry_attempt == 1
end
end

describe "handle_info - connection_closed - with retry - exhausted" do
@describetag private_endpoint: ReconnectExhaustedEndpoint
setup :start_private_endpoint
Expand Down