-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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
Introduce MethodDescriptorSupplier #3086
Conversation
(Splitted into two commit as per @ejona86's suggestion) |
This looks fine to me, other than issues with how the commits were split. Those can either be resolved by reworking what is in each commit or by squashing. @zhangkun83, @carl-mastrangelo, @dapengzhang0, It's important to note that the new APIs introduced to MethodDescriptor, ProtoServiceDescriptorSupplier, and ProtoMethodDescriptorSupplier can't be |
@@ -38,6 +38,7 @@ private BenchmarkServiceGrpc() {} | |||
io.grpc.benchmarks.proto.Messages.SimpleRequest.getDefaultInstance())) | |||
.setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( | |||
io.grpc.benchmarks.proto.Messages.SimpleResponse.getDefaultInstance())) | |||
.setSchemaDescriptor(new BenchmarkServiceFileDescriptorSupplier().getServiceDescriptor().findMethodByName("UnaryCall")) |
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.
This should have just been .setSchemaDescriptor(new BenchmarkServiceFileDescriptorSupplier())
/** | ||
* Provides access to the underlying proto service descriptor. | ||
*/ | ||
public interface ProtoServiceDescriptorSupplier extends ProtoFileDescriptorSupplier { |
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 had intended that this would be in the second commit as well.
@ejona86 squashing will be easier if that works? |
136558d
to
1f588fd
Compare
@ejona86 rebased and squashed into one commit. |
/** | ||
* Provides access to the underlying proto service method descriptor. | ||
*/ | ||
public interface ProtoMethodDescriptorSupplier { |
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.
Extend ProtoServiceDescriptorSupplier
?
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.
Done
LGTM |
"private static final class $proto_method_descriptor_supplier$ extends $proto_file_descriptor_supplier$ implements $ProtoMethodDescriptorSupplier$ {\n"); | ||
p->Indent(); | ||
p->Print(*vars, "private final String methodName;\n\n"); | ||
p->Print(*vars, "public $proto_method_descriptor_supplier$(String methodName) {\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.
private
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.
Done
} | ||
} | ||
|
||
private static final class BenchmarkServiceMethodDescriptorSupplier extends BenchmarkServiceFileDescriptorSupplier implements io.grpc.protobuf.ProtoMethodDescriptorSupplier { |
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.
Why extend? What if the service descriptor isn't available? Services have-a set of methods. Methods fail the is-a
test. So too with the supplier.
Perhaps a method could be added to get the serviceDescriptorSupplier for the method?
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.
protobuf's MethodDescriptor.getService()
is guaranteed to work.
@@ -42,6 +42,7 @@ | |||
private final String fullMethodName; | |||
private final Marshaller<ReqT> requestMarshaller; | |||
private final Marshaller<RespT> responseMarshaller; | |||
private final Object schemaDescriptor; |
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.
@Nullable
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.
Done
* | ||
* @since 1.5.0 | ||
*/ | ||
public Object getSchemaDescriptor() { |
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.
@Nullable
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.
Done
/** | ||
* Provides access to the underlying proto service method descriptor. | ||
*/ | ||
public interface ProtoMethodDescriptorSupplier { |
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.
@DoNotMock
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.
DoNotMock an interface? What would break?
/** | ||
* Returns method descriptor to the proto service method. | ||
*/ | ||
MethodDescriptor getMethodDescriptor(); |
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.
@CheckReturnValue
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.
Done
|
||
p->Print( | ||
*vars, | ||
"private static final class $proto_method_descriptor_supplier$ extends $proto_file_descriptor_supplier$ implements $ProtoMethodDescriptorSupplier$ {\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.
So far grpc generated code is fairly readable. One of the things that makes it that way is generally fitting within line limits. Until we auto format code, could this be wrapped to try to fit? Google style is binary ops go on the following line. Something like:
class Foo
extends Bar
implements Baz
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.
Done
I'm curious how this will interact with the existing schema objects for marshallers. What should the relationship be? (can one be null but not the other? Vice-versa?, Should marshaller schema be removed?) |
@carl-mastrangelo, there aren't schema objects for marshallers. There are schema objects for services though. It seems necessary to have a separate places to store them. We could use the same schema object for both, though (although then it takes more work to lookup the proto MethodDescriptor). |
@carl-mastrangelo addressed your comments, PTAL |
@carl-mastrangelo, ping |
@@ -392,11 +396,32 @@ public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserv | |||
} | |||
} | |||
|
|||
private static final class WorkerServiceDescriptorSupplier implements io.grpc.protobuf.ProtoFileDescriptorSupplier { | |||
private static class WorkerServiceFileDescriptorSupplier |
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 would prefer if this class could be final, since every other class in this generate code is final too.
What do you think about making this final, making a static instance on the MethodDescriptorSupplier
, and having MethodDescriptorSupplier
implement the interfaces here?
(non final classes, even private ones can be mocked by spying instances of them. This was the cause of a recent test breakage)
@java.lang.Override | ||
public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() { | ||
return io.grpc.benchmarks.proto.Services.getDescriptor(); | ||
} | ||
|
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.
This need a package-private constructor. A private ctor causes synthetic classes to be made, and a public one makes reflection too easy.
implements io.grpc.protobuf.ProtoMethodDescriptorSupplier { | ||
private final String methodName; | ||
|
||
private WorkerServiceMethodDescriptorSupplier(String methodName) { |
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.
This should be package-protected too.
extends WorkerServiceFileDescriptorSupplier | ||
implements io.grpc.protobuf.ProtoMethodDescriptorSupplier { | ||
private final String methodName; | ||
|
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.
Another alternative would be to nest the MethodDescriptorSupplier
class as an inner class of the FileDescriptorSupplier
class, and let it capture the fields and methods.
@lukaszx0, it seems there are only small changes remaining. Want to fix them up, or us to? |
@carl-mastrangelo, PTAL. Does this work for you? I created a base abstract class and extend it for both file and method descriptors, which are then both final. I also took the liberty to make java_generator.cpp use a giant string for the block of code, which makes it much more readable and easier to modify for me. |
@carl-mastrangelo, friendly ping. |
* sets this value, in order to be consumed by the server reflection service. See also: | ||
* {@code io.grpc.protobuf.ProtoMethodDescriptorSupplier}. | ||
* | ||
* @since 1.5.0 |
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.
1.7.0
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.
A few minor comments but LGTM
|
||
/** | ||
* Provides access to the underlying proto service method descriptor. | ||
*/ |
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.
Would you mind adding a @Since
here too?
|
||
/** | ||
* Provides access to the underlying proto service descriptor. | ||
*/ |
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.
And here?
@carl-mastrangelo, can you review #3451? It includes the fixes requested (plus another one I noticed). I couldn't push to lukaszx0's branch, so I needed to create a new PR. |
Merged as part of #3451 |
Second iteration on providing an easier way to access service methods which I took stab at in #2904.
It introduces new
MethodDescriptorSupplier
andMethodDescriptor#setSchemaDescriptor
.cc @ejona86