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
Add C# LiteClientBase and "lite_client" codegen option #18705
Conversation
/// is provided by decorating the call invoker. | ||
/// Note: experimental API that can change or be removed without any prior notice. | ||
/// </summary> | ||
public abstract class LiteClientBase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the name of the class is TBD.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CoreClientBase? NetCoreClientBase? ManagedClientBase?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the alternative also runs on .NET Core. I prefer ManagedClientbase as suggested in https://github.com/grpc/grpc-dotnet/pull/180/files.
3e8fc1d
to
70a8f5b
Compare
70a8f5b
to
9f5b894
Compare
@JamesNK @JunTaoLuo I haven't quite figured out the name of the protoc plugin option yet, but the LiteClientBase and protoc plugin changes are mostly done. Worth taking an initial look. |
/// <summary> | ||
/// Call invoker that throws <c>NotImplementedException</c> for all requests. | ||
/// </summary> | ||
private class UnimplementedCallInvoker : CallInvoker |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can move UnimplementedCallInvoker from Grpc.Core to Grpc.Core.Api and reuse it here instead of creating a private class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would then need to be public or internal (there is an internals visible to attribute that gives access to Grpc.Core). I don't think either is worth the hassle compared to some copy and paste.
Edit: we spoke about this offline and I'm okay with ClientBase and LiteClientBase side by side. However, I think the default should only generate ClientBase so there's no change from previous behaviour. We can independently opt in to LiteClientBase or opt out of ClientBase with options. It looks like by default, both a ClientBase and a LiteClientBase will be generated. I'm not sure if that's the best option since current client projects will be bloated after upgrading. The fact that no one should ever need to have both ClientBase and LiteClientBase side by side, I would modify the logic so only one of them is generated, not both. For example, add a
|
/// is provided by decorating the call invoker. | ||
/// Note: experimental API that can change or be removed without any prior notice. | ||
/// </summary> | ||
public abstract class LiteClientBase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CoreClientBase? NetCoreClientBase? ManagedClientBase?
/// <summary> | ||
/// Call invoker that throws <c>NotImplementedException</c> for all requests. | ||
/// </summary> | ||
private class UnimplementedCallInvoker : CallInvoker |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would then need to be public or internal (there is an internals visible to attribute that gives access to Grpc.Core). I don't think either is worth the hassle compared to some copy and paste.
9f5b894
to
81a2c84
Compare
After some delay, I think this is now ready for final review. Here are some modifications I made:
Usage scenarios:
|
@apolcyn @JunTaoLuo @JamesNK PTAL. |
Who sets the option? Have you thought about the name anymore? re: #18705 (comment) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
general comment: can we generate lite_client protos on one of the examples or tests? it may help for comparing diffs later
out->Print("public partial class $name$ : grpc::ClientBase<$name$>\n", | ||
"name", GetClientClassName(service)); | ||
} else { | ||
out->Print("/// <summary>Lite client for $servicename$</summary>\n", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: it may help to add a "experimental API" comment to this generated doc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a version of math.proto
that uses the lite_client option and I checked in the generated code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with two nits. In particular I'd prefer to check in new generated stubs from lite_client mode here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JamesNK We would most likely set the --lite_client option in a build target in Grpc.AspNetCore.Server.
I'm not super familiar with how the proto generator works. So would |
Yes, except to be precise, the option is not passed to the plugin as |
Based on #18532
To allow creating client stubs while only depending on Grpc.Core.Api (= the managed code).
To make this useable, we would also need to add experimental codegen option to generate the lite stubs in codegen.
Some more context in the doc grpc/grpc-dotnet#180. Note that we haven't figured out many questions around the client-side API (and how to expose the concept of a "client channel", along with all its functionality), so the solution with "LiteClientBase" might be temporary.