Совместимость между сервером gRPC в Go и клиентом в Python - PullRequest
0 голосов
/ 24 июня 2018

Я хочу узнать о совместимости службы gRPC в Go и клиента в Python.

Например, , если служба реализована в Go , она будет иметь такие подписи:

...

func (s *routeGuideServer) GetFeature(ctx context.Context, point *pb.Point) (*pb.Feature, error) {
        ...
}
...

func (s *routeGuideServer) ListFeatures(rect *pb.Rectangle, stream pb.RouteGuide_ListFeaturesServer) error {
        ...
}
...

func (s *routeGuideServer) RecordRoute(stream pb.RouteGuide_RecordRouteServer) error {
        ...
}
...

func (s *routeGuideServer) RouteChat(stream pb.RouteGuide_RouteChatServer) error {
        ...
}

Обратите внимание, как error объекты возвращаются.

Теперь, если мне нужно реализовать клиент на Python, это будет примерно так :

feature = stub.GetFeature(point)
for received_route_note in stub.RouteChat(sent_route_note_iterator):

Что происходит с полем error, которое возвращается реализацией службы Go? Если существует ошибка со стороны сервера, как ее можно обработать в клиенте Python?

1 Ответ

0 голосов
/ 24 июня 2018

gRPC обеспечивает обработку ошибок, соответствующую используемому языку.

Как вы отметили, на Go сервере вы возвращаете ошибку:

func (s *routeGuideServer) RouteChat(stream pb.RouteGuide_RouteChatServer) error {
for {
    in, err := stream.Recv()
    if err == io.EOF {
        return nil
    }
    if err != nil {
        return err
    }
    ...

ВКлиент Python, вы выполняете вызов API в операторе try (надуманный пример, поскольку официальная документация не демонстрирует этого):

while True:
  try:
    received_route_note = stub.RouteChat(sent_route_note_iterator)
  except grpc.Error as e:
    print(e.details())
    break

И наоборот, на сервере Python вы устанавливаете контекст инеобязательно, вызвать исключение:

  • пример из Ссылка на сгенерированный Python код :

    def TellFortune(self, request, context):
      """Returns the horoscope and zodiac sign for the given month and day.
      errors: invalid month or day, fortune unavailable
      """
      context.set_code(grpc.StatusCode.UNIMPLEMENTED)
      context.set_details('Method not implemented!')
      raise NotImplementedError('Method not implemented!')
    
  • пример из репозиторий grpc

    def UnUn(self, request, context):
      if _application_common.UNARY_UNARY_REQUEST == request:
          return _application_common.UNARY_UNARY_RESPONSE
      else:
          context.set_code(grpc.StatusCode.INVALID_ARGUMENT)
          context.set_details('Something is wrong with your request!')
          return services_pb2.Down()
    

И в Go клиенте объект error является (одним из) параметров результата:

stream, err := client.RouteChat(ctx)
if err != nil {
    log.Fatalf("%v.RouteChat(_) = _, %v", client, err)
}

К сожалению, официальная документация явно не охватывает практики обработки ошибок.

Хорошая сторонняя ссылка, которую я нашел, находится по адресу http://avi.im/grpc-errors/

...