Skip to content

Conversation

@mrmicahcooper
Copy link
Contributor

@mrmicahcooper mrmicahcooper commented Jan 23, 2026

Allow a GRPC.Channel to be created with a name.

This removes the need for developers to store the Channel that's returned from GRPC.Client.Connection.connect.

This is one attempt to solve the feedback I previously mentioned in a separate issue:
#464 (comment)

I'll explain how I do things now and what this PR is attempting to do:

Current

I have an elixir app that talks to a GRPC endpoint.
So I say {:ok, channel} = GRPC.Stub.connect("https://grpc.endpoint.com")
Now, I need to hold on to this channel somewhere so I can use it later so I create a GenServer with this channel in its state.
Now I call the GenServer which uses the channel in its state to forward the request to the GRPC stub.
Something like HelloWorld.Stub.say_hello(channel, "hello")
This works and has the ability to ensure the GRPC.Client.Supervisor is started before we start this GenServer starts.
The downside is now I have to have an entire process just to store a virtual channel.

Proposed

Use a module attribute to store the name of the channel I want.
@endpoint_channel :my_service_channel
Now create a channel with that name and ignore the response:
{:ok, _channel} = GRPC.Client.Connection.connect("https://grpc.endpoint.com", name: @enpdoint_channel)
When I want to use that channel, I use the predetermined name:
Something like HelloWorld.Stub.say_hello(%Channel{ref: @endpoint_channel}), "hello")
Now I don't need to store that channel anywhere.

This PR implements the "proposed" and ignores the fact that you'd have to manually create this connection somewhere in your app after the GRPC.Client.Supervisor is started.

Something that might be cool is the ability to create these named channels in config.
But this PR seems like a really low risk way add this feature.

I'd love any feedback or thoughts about a different approach.

Thanks!

Allow a GRPC.Channel to be created with a name.
This removes the need for developers to store the `Channel` that's
returned from `GRPC.Client.Connection.connect`.
Copy link
Collaborator

@sleipnir sleipnir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, I thinik this is cool.
But if we're going to do this (expose named channels), maybe it would be better to use a Registry and allow managing multiple channels.
WDYT @polvalente ?

@mrmicahcooper
Copy link
Contributor Author

Overall, I thinik this is cool. But if we're going to do this (expose named channels), maybe it would be better to use a Registry and allow managing multiple channels. WDYT @polvalente ?

I have no strong opinions on an implementation as you are much closer to the the project than I am. This PR was more to exemplify the desired feature.

end

ref = make_ref()
{ref, opts} = Keyword.pop(opts, :name, make_ref())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible for us to use Keyword.validate in this function to help document the options? If so, we can just have name: make_ref() in the option arguments there

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +71 to +78
@channel_name :my_channel
test "use a channel name to send a message" do
run_server(HelloServer, fn port ->
{:ok, _channel} =
GRPC.Client.Connection.connect("localhost:#{port}",
interceptors: [GRPC.Client.Interceptors.Logger],
name: @channel_name
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@channel_name :my_channel
test "use a channel name to send a message" do
run_server(HelloServer, fn port ->
{:ok, _channel} =
GRPC.Client.Connection.connect("localhost:#{port}",
interceptors: [GRPC.Client.Interceptors.Logger],
name: @channel_name
)
test "use a channel name to send a message" do
run_server(HelloServer, fn port ->
{:ok, _channel} =
GRPC.Client.Connection.connect("localhost:#{port}",
interceptors: [GRPC.Client.Interceptors.Logger],
name: :my_channel
)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for the module attribute. Maybe if this was a macro behavior could be different, but given that it's a function, we can just rely on the atom value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants