From 5883c4adbe4c5dee264004c869fcd57299847843 Mon Sep 17 00:00:00 2001 From: Luis Gustavo Beligante Date: Mon, 1 Jul 2024 19:06:48 -0300 Subject: [PATCH] gracefully handles server process shutdown --- lib/grpc/server/adapters/cowboy/handler.ex | 4 +-- test/grpc/integration/server_test.exs | 21 ++++++++++++ test/support/google/api/annotations.pb.ex | 8 ----- test/support/google/api/http.pb.ex | 40 ---------------------- 4 files changed, 23 insertions(+), 50 deletions(-) delete mode 100644 test/support/google/api/annotations.pb.ex delete mode 100644 test/support/google/api/http.pb.ex diff --git a/lib/grpc/server/adapters/cowboy/handler.ex b/lib/grpc/server/adapters/cowboy/handler.ex index 836e9f5f..1fad43a5 100644 --- a/lib/grpc/server/adapters/cowboy/handler.ex +++ b/lib/grpc/server/adapters/cowboy/handler.ex @@ -449,8 +449,8 @@ defmodule GRPC.Server.Adapters.Cowboy.Handler do end end - def info({:EXIT, pid, :normal}, req, state = %{pid: pid}) do - exit_handler(pid, :normal) + def info({:EXIT, server_rpc_pid, reason}, req, state = %{pid: server_rpc_pid}) + when reason in [:normal, :shutdown] do {:stop, req, state} end diff --git a/test/grpc/integration/server_test.exs b/test/grpc/integration/server_test.exs index 7a6ae8cd..e4e344de 100644 --- a/test/grpc/integration/server_test.exs +++ b/test/grpc/integration/server_test.exs @@ -7,6 +7,12 @@ defmodule GRPC.Integration.ServerTest do def get_feature(point, _stream) do %Routeguide.Feature{location: point, name: "#{point.latitude},#{point.longitude}"} end + + def route_chat(_ex_stream, stream) do + GRPC.Server.send_headers(stream, %{}) + Process.exit(self(), :shutdown) + Process.sleep(500) + end end defmodule TranscodeErrorServer do @@ -320,6 +326,21 @@ defmodule GRPC.Integration.ServerTest do end) end + test "gracefully handles server shutdown disconnects" do + logs = + ExUnit.CaptureLog.capture_log(fn -> + run_server(FeatureServer, fn port -> + {:ok, channel} = GRPC.Stub.connect("localhost:#{port}") + client_stream = Routeguide.RouteGuide.Stub.route_chat(channel) + assert %GRPC.Client.Stream{} = client_stream + {:ok, ex_stream} = GRPC.Stub.recv(client_stream, timeout: :infinity) + assert [{:error, %GRPC.RPCError{status: 13}}] = Enum.into(ex_stream, []) + end) + end) + + assert logs == "" + end + describe "http/json transcode" do test "grpc method can be called using json when http_transcode == true" do run_server([TranscodeServer], fn port -> diff --git a/test/support/google/api/annotations.pb.ex b/test/support/google/api/annotations.pb.ex deleted file mode 100644 index 374877d3..00000000 --- a/test/support/google/api/annotations.pb.ex +++ /dev/null @@ -1,8 +0,0 @@ -defmodule Google.Api.PbExtension do - @moduledoc false - use Protobuf, protoc_gen_elixir_version: "0.11.0", syntax: :proto3 - - extend Google.Protobuf.MethodOptions, :http, 72_295_728, - optional: true, - type: Google.Api.HttpRule -end diff --git a/test/support/google/api/http.pb.ex b/test/support/google/api/http.pb.ex deleted file mode 100644 index ebd043a6..00000000 --- a/test/support/google/api/http.pb.ex +++ /dev/null @@ -1,40 +0,0 @@ -defmodule Google.Api.Http do - @moduledoc false - use Protobuf, protoc_gen_elixir_version: "0.11.0", syntax: :proto3 - - field :rules, 1, repeated: true, type: Google.Api.HttpRule - - field :fully_decode_reserved_expansion, 2, - type: :bool, - json_name: "fullyDecodeReservedExpansion" -end - -defmodule Google.Api.HttpRule do - @moduledoc false - use Protobuf, protoc_gen_elixir_version: "0.11.0", syntax: :proto3 - - oneof :pattern, 0 - - field :selector, 1, type: :string - field :get, 2, type: :string, oneof: 0 - field :put, 3, type: :string, oneof: 0 - field :post, 4, type: :string, oneof: 0 - field :delete, 5, type: :string, oneof: 0 - field :patch, 6, type: :string, oneof: 0 - field :custom, 8, type: Google.Api.CustomHttpPattern, oneof: 0 - field :body, 7, type: :string - field :response_body, 12, type: :string, json_name: "responseBody" - - field :additional_bindings, 11, - repeated: true, - type: Google.Api.HttpRule, - json_name: "additionalBindings" -end - -defmodule Google.Api.CustomHttpPattern do - @moduledoc false - use Protobuf, protoc_gen_elixir_version: "0.11.0", syntax: :proto3 - - field :kind, 1, type: :string - field :path, 2, type: :string -end