grpc с методом mustEmbedUnimplemented ***

#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 прямая совместимость становится невозможной, что означает две вещи:

  1. теперь вы должны выполнить встраивание UnimplementedFooBarServiceServer , как следует из сообщения об ошибке. Как я уже сказал, это не приведет к ошибкам компилятора, если вы явно не реализуете новые методы (это означает прямую совместимость). Хотя это приведет к ошибке во время выполнения codes.Unimplemented , если вы попытаетесь вызвать RPC, который вы не (или забыли) явно реализовать.
  2. вы все равно можете отказаться от прямой совместимости, внедрив вместо 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