elixir-grpc / grpc

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

gRPC HTTP/2 Channel Connection Pooling #345

Closed Nezteb closed 3 months ago

Nezteb commented 9 months ago

Is your feature request related to a problem? Please describe.

Consumers of elixir-grpc could run into scalability issues if they don't handle the multiplexing capabilities of the HTTP/2 connections elixir-grpc exposes; instead they will probably create a single channel and re-use it for every connection. Mint defaults :max_concurrent_streams to 100; this can be configured but doesn't seem ideal. While looking into strategies to deal with this, I found an old GH issue related to gRPC connection pooling. Two of the comments mention that pooling isn't ideal for HTTP2 connections:

Just keeping multiple connections open, monitoring their status and spreading the load across them should be fine and won't introduce the unnecessary contention a connection pool would.

You can use registries here as a pool since you don’t want to lock the connection from being multiplexed on. A registry that is host -> channel would be sufficient. Enabling duplicate keys could allow you to have multiple connections in here and then you can just do something like Enum.random(channels) on the results of your registry select call and that would probably be sufficient.

Describe the solution you'd like

Since the maintainer consensus is "avoid pooling" I think it would be wise to cover this in the form of some docs, preferably with a few examples. Do others agree? Are there any thoughts on what it could/should cover?

Describe alternatives you've considered

If the maintainers are comfortable delegating the "how do I pool gRPC HTTP/2 connections in Elixir" question to another library, there is conn_grpc, which exposes a @behaviour for handling backoff.

Yordis on the Elixir Slack also pointed out to me that a package called spear implements its own HTTP/2 connection pooling.

Nezteb commented 9 months ago

Initially I thought the elixir-grpc maintainers' opinion was that the idea of "grpc http/2 connection pooling" belonged in a different library, which is why I framed this as a documentation issue. After talking with @polvalente in the Elixir Slack, I realize that there is interest in this so I'm going to edit the issue title slightly.

I'd like to eventually take a shot at on implementing this using the methods described in the following articles:

I probably won't look more into this until Jan/Feb 2024. 😄

v0idpwn commented 5 months ago

Alongside connection pooling, it would be great to have load balancing. It should be relatively easy to implement it on top of a routing pool, just need to diversify the pool with connections from different hosts.

sleipnir commented 3 months ago

Closed by #350