gpt4 book ai didi

go - gRPC 可能出现零服务器消息吗?

转载 作者:IT王子 更新时间:2023-10-29 01:40:29 35 4
gpt4 key购买 nike

在下面的gRPC客户端代码中,第二个if是否必要?

status, err := cli.GetStatus(ctx, &empty.Empty{})
if err != nil {
return err
}

if status == nil {
// this should NEVER happen - right?
return fmt.Errorf("nil Status result returned")
}

直觉上,应该总是在 go 中检查 nil 以防万一。但是,有一个运行时检查来捕获任何客户端到服务器的 nil 用法,例如

status, err := cli.GetStatus(ctx, nil) // <- runtime error

if err != nil {
// "rpc error: code = Internal desc = grpc: error while marshaling: proto: Marshal called with nil"
return err
}

那么是否有类似的服务器到客户端运行时保证,从而消除对 status == nil 检查的需要?

最佳答案

进一步调查人为的服务器示例:

func (s *mygRPC) GetStatus(context.Context, *empty.Empty) (*pb.Status, error) {
log.Println("cli: GetStatus()")

//return &pb.Status{}, nil
return nil, nil // <- can server return a nil status message (with nil error)
}

并测试客户端/服务器的 react :

客户:

ERROR: rpc error: code = Internal desc = grpc: error while marshaling: proto: Marshal called with nil

服务器:

2019/05/14 16:09:50 cli: GetStatus()
ERROR: 2019/05/14 16:09:50 grpc: server failed to encode response: rpc error: code = Internal desc = grpc: error while marshaling: proto: Marshal called with nil

因此,即使有人想合法地返回一个 nil 值,gRPC 传输也不允许。

注意:服务器端代码仍在执行 - 正如预期的那样 - 但就客户端而言,gRPC 调用失败。

结论:一个有效的(err==nil)服务器响应将总是返回一个有效的(非nil) 消息。


编辑:

检查 gRPC 源代码揭示了捕获 nil 消息的位置:

server.go

func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg interface{}, cp Compressor, opts *transport.Options, comp encoding.Compressor) error {
data, err := encode(s.getCodec(stream.ContentSubtype()), msg)
if err != nil {
grpclog.Errorln("grpc: server failed to encode response: ", err)
return err
}
// ...
}

rpc_util.go

func encode(c baseCodec, msg interface{}) ([]byte, error) {
if msg == nil { // NOTE: typed nils will not be caught by this check
return nil, nil
}
b, err := c.Marshal(msg)
if err != nil {
return nil, status.Errorf(codes.Internal, "grpc: error while marshaling: %v", err.Error())
}
// ...
}

这一行的注释是关键:

if msg == nil { // NOTE: typed nils will not be caught by this check }

因此,如果对我们的 typed-nil 使用 reflect,reflect.ValueOf(msg).IsNil() 将返回 true。以下 c.Marshal(msg) 错误 - 调用无法向客户端发送消息响应。

关于go - gRPC 可能出现零服务器消息吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56119785/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com