-
Notifications
You must be signed in to change notification settings - Fork 946
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve ergonomics when passing Clients as function arguments #110
Comments
An easy workaround is to use a concrete type instead of the type parameter. Currently, I believe the only concrete type that can be used to construct a client is a async fn foo(mut client: MyClient<Channel>) {...} Here's an example: |
Huh, that totally solves my particular issue. Not sure why I didn't think of that earlier! That said, there are times when it might be useful to write transport-independent functions. For example, a API might require first calling |
I agree, you raise a good point. I believe there are plans (and maybe even some initial work) to provide different transports, in which case we may need to find a different solution. |
These bounds work, but will result in some broken code once we switch to a proper sockets-based transport. I've opened an issue upstream, since it would be nice to keep the more generic code, while somehow avoiding boilerplate. hyperium/tonic#110
@daniel5151 yeah, so I tried to get https://docs.rs/tonic/0.1.0-alpha.5/tonic/client/trait.GrpcService.html to do as much of that work as possible but it seemed that rust was not happen. Sounds like this would be a good thing to revisit. |
These bounds work, but will result in some broken code once we switch to a proper sockets-based transport. I've opened an issue upstream, since it would be nice to keep the more generic code, while somehow avoiding boilerplate. hyperium/tonic#110
These bounds work, but will result in some broken code once we switch to a proper sockets-based transport. I've opened an issue upstream, since it would be nice to keep the more generic code, while somehow avoiding boilerplate. hyperium/tonic#110
So, what @alce said (about |
Interceptors can be made using named types by implementing the |
Sure, but that will only get rid of the |
In 2023 I don't think much has changed in terms of making naming client types any easier. Is there any interest in having the generated client implement the generated service trait? If so, I'm happy to contribute. |
I'm running into this while trying to use Tower middleware. Using a service builder means that I now have a pretty deeply nested type instead of a channel. The following example spits outs a let channel = ServiceBuilder::new()
.timeout(Duration::from_secs(30))
.layer(tonic::service::interceptor(my_cool_interceptor(
ctx.clone(),
)))
.layer(tonic::service::interceptor(|req| Ok(req)))
.service(channel); Some (generated?) documentation about the bounds to include when passing a client to a fn would be awesome. |
Just chiming in, I'm also hitting this issue in the context of trying to store the tonic client inside of my own struct.
I then use a tower |
Feature Request
Motivation
At the moment, any function that takes a Client as a parameter requires specifying some pretty scary-looking type bounds:
It would be nice to somehow simplify these sorts of declarations.
Proposal
I'm not entirely sure how to work around this issue!
A heavyweight solution might be to write a proc macro that automagically includes these type bounds on a function. e.g:
Alternatives
There are probably other, simpler solutions, but I can't think of any great ones off the top of my head. That said, I don't have a thorough understanding of tonic internals, so maybe there is an easy fix.
The text was updated successfully, but these errors were encountered: