【问题标题】:Compatibility between a gRPC server in Go and a client in PythonGo 中的 gRPC 服务器和 Python 中的客户端之间的兼容性
【发布时间】:2018-06-24 18:25:22
【问题描述】:

我想了解 Go 中的 gRPC 服务和 Python 中的客户端的兼容性。

例如if the service is implemented in 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 对象的返回方式。

现在,如果我必须implement the client in Python it will be something like this

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

Go 服务实现返回的 error 字段会发生什么情况?如果服务器端出现错误,Python客户端如何处理?

【问题讨论】:

    标签: python go grpc


    【解决方案1】:

    gRPC 提供适合所使用语言的错误处理。

    如您所述,在 Go server 中您返回错误:

    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 客户端中,您在 try 语句中执行 API 调用(人为的示例,因为官方文档没有说明这一点):

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

    相反,在 Python 服务器中,您可以设置上下文,并且可以选择引发异常:

    • 来自Python Generated Code Reference 的示例:

      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 repository的示例

      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 client 中,error 对象是结果参数(之一):

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

    很遗憾,官方文档似乎没有明确涵盖错误处理实践。

    我在http://avi.im/grpc-errors/找到了一个很好的第 3 方参考

    【讨论】:

      猜你喜欢
      • 2018-11-15
      • 2013-02-02
      • 2019-11-05
      • 1970-01-01
      • 1970-01-01
      • 2020-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多