Skip to content
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 BindServiceAttribute #18484

Merged
merged 7 commits into from
Apr 5, 2019

Conversation

JamesNK
Copy link
Member

@JamesNK JamesNK commented Mar 24, 2019

Add a BindServiceAttribute so .NET libraries can easily resolve the location of the bind service method for a gRPC service.

// @jtattermusch

grpc/grpc-dotnet#107

@JamesNK
Copy link
Member Author

JamesNK commented Mar 24, 2019

btw I don't have all of the C++ tools setup on this computer. Hopefully it compiles 🤞

Copy link
Contributor

@jtattermusch jtattermusch left a comment

Choose a reason for hiding this comment

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

Formatting is off (we enforce clang format on C/C++ code).

+ tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh
--- /var/local/git/grpc/src/compiler/csharp_generator.cc	2019-03-24 20:29:22.482677999 +0000
+++ /tmp/tmp.b6a8NEqD8T	2019-03-24 20:32:14.650677999 +0000
@@ -383,7 +383,8 @@
       "$servicename$</summary>\n",
       "servicename", GetServiceClassName(service));
   out->Print(
-      "[grpc::BindService(typeof($classname$), nameof($classname$.BindService))]\n",
+      "[grpc::BindService(typeof($classname$), "
+      "nameof($classname$.BindService))]\n",
       "classname", GetServiceClassName(service));
   out->Print("public abstract partial class $name$\n", "name",
              GetServerClassName(service));

src/csharp/Grpc.Core.Api/BindServiceAttribute.cs Outdated Show resolved Hide resolved
src/csharp/Grpc.Core.Api/BindServiceAttribute.cs Outdated Show resolved Hide resolved
Copy link
Contributor

@jtattermusch jtattermusch left a comment

Choose a reason for hiding this comment

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

A few more comments (and I pushed a fix for one of them and the regenerated code).

@@ -382,6 +382,10 @@ void GenerateServerClass(Printer* out, const ServiceDescriptor* service) {
"/// <summary>Base class for server-side implementations of "
"$servicename$</summary>\n",
"servicename", GetServiceClassName(service));
out->Print(
"[grpc::BindService(typeof($classname$), "
"nameof($classname$.BindService))]\n",
Copy link
Contributor

Choose a reason for hiding this comment

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

nameof() is a C# 6 concept and as of now, the generated code does not require C# 6. I know C# 6 is pretty old already, but we can easily use a string "BindService" instead of nameof() and remove the concern.

Copy link
Contributor

Choose a reason for hiding this comment

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

GetServiceClassName(service) only gives the name of the class, but we should probably use a fully qualified name to eliminate potential name collisions.

Copy link
Member Author

@JamesNK JamesNK Mar 25, 2019

Choose a reason for hiding this comment

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

but we should probably use a fully qualified name to eliminate potential name collisions.

I thought about that but there are other places in the generated service that reference class names without fully qualifying them.

@jtattermusch jtattermusch added lang/C# release notes: yes Indicates if PR needs to be in release notes labels Mar 25, 2019
@@ -67,6 +67,7 @@ public static partial class Math
}

/// <summary>Base class for server-side implementations of Math</summary>
[grpc::BindService(typeof(Math), "BindService")]
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: TBH i'm still not 100% convinced by the name [BindService], I don't feel the name fully conveys what the attribute stands for. Have we considered some alternative names?

Copy link
Member Author

@JamesNK JamesNK Mar 25, 2019

Choose a reason for hiding this comment

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

I'm open to alternatives.

[ServiceBind(...)]
[ServiceBinder(...)]
[ServiceBindMethod(...)]
[BindMethod(...)]

@@ -0,0 +1,53 @@
#region Copyright notice and license
// Copyright 2015 gRPC authors.

Choose a reason for hiding this comment

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

nit: 2019

@JamesNK
Copy link
Member Author

JamesNK commented Apr 1, 2019

Does anything else need to be done here? Can we merge this for 1.20? I'm ok with [BindServiceMethod] as the attribute name.

@jtattermusch
Copy link
Contributor

@JamesNK I thought we left the exact attribute name and arguments open in relation to Server Reflection as "needs more thought".

@JamesNK
Copy link
Member Author

JamesNK commented Apr 1, 2019

I implemented server reflection here - https://github.com/grpc/grpc-dotnet/pull/192/files#diff-811a02dca4701b0d502640e0d18407b7R48

I've thought about it and there are three choices:

  1. Change attribute name to something generic like ServiceDefinition and add DescriptorName to it. The problem with this is if there is ever a situation where the Descriptor and BindMethod are on different types then you're stuck because you're specifying the same type for both. Will this ever happen? Probably not, but might as well not limit ourselves unnecessarily.
  2. Add a new attribute for the descriptor and have two attributes on the base class. ServiceDescriptor? Its clean but IMO overkill. BindMethod and Descriptor are always generated on the same class. If that ever changes we could always add a new attribute in the future.
  3. Reuse BindMethodName to get the type. Simplest thing and it will always work unless codegen radically changes.

I'm ok with 3.

@JamesNK
Copy link
Member Author

JamesNK commented Apr 1, 2019

I slightly perfer [ServiceBindMethod] over the current [BindServiceMethod] name. But it isn't important to me.

@jtattermusch
Copy link
Contributor

I slightly perfer [ServiceBindMethod] over the current [BindServiceMethod] name. But it isn't important to me.

I chose [BindServiceMethod] because the method is called BindService and I felt reversing the word order would only create confusion.

Copy link
Contributor

@jtattermusch jtattermusch left a comment

Choose a reason for hiding this comment

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

LGTM.

@jtattermusch
Copy link
Contributor

Known failures:
#18637
#18655
#18416

@jtattermusch jtattermusch merged commit 9144c6a into grpc:master Apr 5, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Jul 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
lang/C# release notes: yes Indicates if PR needs to be in release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants