elixir-grpc / grpc

An Elixir implementation of gRPC
https://hex.pm/packages/grpc
Apache License 2.0
1.36k stars 210 forks source link

Support `cowboy`/`ranch_tcp` opts: `inet`, `inet6`, `ipv6_only` #305

Closed Nezteb closed 1 year ago

Nezteb commented 1 year ago

Is your feature request related to a problem? Please describe. elixir-grpc uses cowboy, which uses ranch for listening on TCP sockets. ranch supports several config options like inet, inet6, and ipv6_only. https://ninenines.eu/docs/en/ranch/1.7/manual/ranch_tcp/

From what I can tell, it seems like elixir-grpc strips out most cowboy configuration options here: https://github.com/elixir-grpc/grpc/blob/f21e2e1bcf48c3a2991b61ed8675e9159fa5872c/lib/grpc/server/adapters/cowboy.ex#L222-L239

I'm working on a service that uses elixir-grpc that we want to listen with both IPv4 and IPv6, and eventually move to only supporting IPv6 communication. Given the above, I don't think that's currently possible with elixir-grpc.

Describe the solution you'd like I might be wrong; there might be a way to support both IPv4 and IPv6 (as well as only IPv6) already in elixir-grpc with some configuration tweaking. I just can't find any obvious way to do that.

plug_cowboy supports these options: https://hexdocs.pm/plug_cowboy/Plug.Cowboy.html#module-options

The difference seems to be that plug_cowboy doesn't filter out options: https://github.com/elixir-plug/plug_cowboy/blob/1796e77aa42c2284f3667c7aeac7074236f47c07/lib/plug/cowboy.ex#L254-L302

Describe alternatives you've considered N/A.

Additional context N/A.

polvalente commented 1 year ago

A PR extending the current behavior is welcome!

Nezteb commented 1 year ago

@polvalente I've pulled in the master branch of grpc as a dependency to my project and realized: I don't know if I can configure the Cowboy adapter from the project-level.

Previously I had:

children = [
  # ...
  {GRPC.Server.Supervisor, endpoint: Helloworld.Endpoint, port: 50051}
  # ...
]

I think I just need to do the following?

children = [
  # ...
  {GRPC.Server.Supervisor, endpoint: Helloworld.Endpoint, port: 50051, net: :inet6, ipv6_v6only: true}
  # ...
]

Does that seem right?

polvalente commented 1 year ago

@Nezteb yup, looks like it's right!

https://github.com/elixir-grpc/grpc/blob/4eaf0423b2cb49e540a091e14daa6206a7124667/lib/grpc/server/supervisor.ex#L119

This line will ultimately be called when initializing the GRPC.Server.Supervisor with an :endpoint, and the options are passed to the adapter child_spec/4 function, which is what you actually tested in your PR