'grpc with mustEmbedUnimplemented*** method
Recently, grpc-go introduced the mustEmbedUnimplemented*** method. It is used for forward compatibility.
In simple terms, I am unable to understand how it is helping and how earlier without it what problems we were facing? In my structs now I use to add the following statement but, I don't know why...
type server struct {
pdfpb.UnimplementedGreetServiceServer
}
In Github issue - https://github.com/grpc/grpc-go/issues/3669 they debated over it, can someone please explain in simple terms how it is helping and how earlier without it what problems we were facing?
Solution 1:[1]
That was quite basic.
UnimplementedGreetServiceServer
is a struct with all implemented methods.
When I add pdfpb.UnimplementedGreetServiceServer
I am able to call UnimplementedGreetServiceServer
defined methods.
That's how, if I add more RPC services in the proto file, then I don't need to add all RPC methods leading to forward compatibility.
Demo code is available at: https://github.com/parthw/fun-coding/tree/main/golang/understanding-grpc-change
Solution 2:[2]
This error comes newer versions of the protoc-gen-grpc-go
compiler. Server implementations must now be forward-compatible.
Before this change, whenever you registered a server implementation, you would do something like this:
pb.RegisterFooBarServiceServer(
server,
&FooBarServer{}, // or whatever you use to construct the server impl
)
Which would result in a compile-time error in case your server has some missing method implementations.
With the newer proto compiler version, forward-compatibility becomes opt-out, which means two things:
you must now embed
UnimplementedFooBarServiceServer
, as the error message suggests. As I said, this will not produce compiler errors when you do not explicitly implement new methods (this is what forward compatibility means). Though it will result in a run-time error withcodes.Unimplemented
if you attempt to call an RPC that you didn't (or forgot) to explicitly implement.you can still opt-out of forward compatibility by embedding instead
UnsafeFooBarServiceServer
(withUnsafe
prefix). This interface simply declares themustEmbedUnimplementedFooBarServiceServer()
method which makes the error in the question go away, without forgoing a compiler errors in case you didn't explicitly implement the new handlers.
So for example:
// Implements the grpc FooBarServiceServer
type FooBarService struct {
grpc.UnsafeFooBarServiceServer // consciously opt-out of forward compatibility
// other fields
}
You can also generate code without forward compatibility by setting an option on protoc-gen-grpc-go
plugin (source):
protoc --go-grpc_out=require_unimplemented_servers=false:.
Note the :.
after the --go-grpc_out
option is used to set the path element.
Solution 3:[3]
For anyone that still have problems with mustEmbededUnimplementedServiceServer
as suggested on the Github Issue. the best solution is just to update your ServerStruct.
Ex.
type AuthenticationServiceServer struct {
}
To.
type AuthenticationServiceServer struct {
service.UnimplementedAuthenticationServiceServer
}
that will solve the exception throw by Go when doing this.
grpcService.RegisterAuthenticationServiceServer(grpcServer, controller.AuthenticationServiceServer{})
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | blackgreen |
Solution 2 | |
Solution 3 | Luis Cardoza Bird |