#go #protocol-buffers #grpc-go
# #Вперед #протокол-буферы #grpc-go
Вопрос:
Недавно grpc-go представила метод mustEmbedUnimplemented ***. Он используется для прямой совместимости.
Проще говоря, я не могу понять, как это помогает и как раньше без него, с какими проблемами мы сталкивались? В моих структурах теперь я использую для добавления следующего оператора, но я не знаю почему…
type server struct {
pdfpb.UnimplementedGreetServiceServer
}
В Github проблема — https://github.com/grpc/grpc-go/issues/3669 они спорили по этому поводу, может ли кто-нибудь, пожалуйста, объяснить простыми словами, как это помогает и как раньше без этого, с какими проблемами мы сталкивались?
Ответ №1:
Это было довольно просто.
UnimplementedGreetServiceServer
представляет собой структуру со всеми реализованными методами.
Когда я добавляю pdfpb.UnimplementedGreetServiceServer
, я могу вызывать UnimplementedGreetServiceServer
определенные методы.
Вот как, если я добавлю больше служб RPC в прото-файл, мне не нужно добавлять все методы RPC, ведущие к прямой совместимости.
Демонстрационный код доступен по адресу: https://github.com/parthw/fun-coding/tree/main/golang/understanding-grpc-change
Комментарии:
1. Так что же это на самом деле помогает? Я определенно придерживаюсь мнения, что это не функция и может привести к нарушению работы API. Почему я должен разрешать генерацию файлов proto в файлы go и не реализовывать их?
2. @swade я согласен с вами. Я не хочу, чтобы RPC завершались неудачно,
Unimplemented
если кто-то забудет реализовать обработчик. Однако в этом изменении есть преимущество, которое заключается в том, что теперь вы должны сделать сознательный выбор о том, иметь ли прямую совместимость или нет. С другой стороны, вы можете не захотеть, чтобы при обновлении прототипной схемы выполнялись неудачные сборки, но не реализация grpc. Таким образом, они позволяют вам выбирать. В любом случае вы все равно можете отказаться от fwd compat. Подробности см. в моем ответе
Ответ №2:
Эта ошибка возникает в более новых версиях protoc-gen-grpc-go
компилятора. Серверные реализации теперь должны быть совместимы с прямой связью.
До этого изменения всякий раз, когда вы регистрировали реализацию сервера, вы должны были делать что-то вроде этого:
pb.RegisterFooBarServiceServer(
server,
amp;FooBarServer{}, // or whatever you use to construct the server impl
)
Что приведет к ошибке во время компиляции в случае, если на вашем сервере отсутствуют некоторые реализации метода.
В более новой версии компилятора proto прямая совместимость становится невозможной, что означает две вещи:
- теперь вы должны выполнить встраивание
UnimplementedFooBarServiceServer
, как следует из сообщения об ошибке. Как я уже сказал, это не приведет к ошибкам компилятора, если вы явно не реализуете новые методы (это означает прямую совместимость). Хотя это приведет к ошибке во время выполненияcodes.Unimplemented
, если вы попытаетесь вызвать RPC, который вы не (или забыли) явно реализовать. - вы все равно можете отказаться от прямой совместимости, внедрив вместо
UnsafeFooBarServiceServer
этого (сUnsafe
префиксом). Этот интерфейс просто объявляетmustEmbedUnimplementedFooBarServiceServer()
метод, который устраняет ошибку в вопросе, не отказываясь от ошибок компилятора в случае, если вы явно не внедрили новые обработчики.
Так, например:
// Implements the grpc FooBarServiceServer
type FooBarService struct {
grpc.UnsafeFooBarServiceServer // consciously opt-out of forward compatibility
// other fields
}
Вы также можете генерировать код без прямой совместимости, установив опцию в protoc-gen-grpc-go
плагине (исходном коде):
protoc --go-grpc_out=require_unimplemented_servers=false:.
Обратите :.
--go-grpc_out
внимание, что опция after используется для установки элемента path.
Ответ №3:
Для всех, у кого все еще есть проблемы с mustEmbededUnimplementedServiceServer
, как было предложено в вопросе Github. лучшее решение — просто обновить вашу серверную структуру.
Пример.
type AuthenticationServiceServer struct {
}
Для.
type AuthenticationServiceServer struct {
service.UnimplementedAuthenticationServiceServer
}
это позволит решить проблему исключения с помощью Go при выполнении этого.
grpcService.RegisterAuthenticationServiceServer(grpcServer, controller.AuthenticationServiceServer{})
Комментарии:
1. Пример кода здесь github.com/alexcpn/go_grpc_2022