写 StreamClientInterceptor 时函数,确定调用者何时完成 RPC 的最佳方法是什么?这对于一元拦截器或在您传递 handler 的服务器端非常简单执行 RPC,但不清楚如何在返回 ClientStream 的客户端最好地执行此操作然后调用者与之交互。
这方面的一个用例是检测 OpenTracing,其目标是开始和结束一个跨度以标记 RPC 的开始和结束。
我正在研究的一种策略是让流拦截器返回经过修饰的 ClientStream。如果任何接口(interface)方法Header
、CloseSend
、SendMsg
、RecvMsg
,这个新的 ClientStream 认为 RPC 已经完成返回错误或者 Context
被取消。此外,它将此逻辑添加到 RecvMsg
:
func (cs *DecoratedClientStream) RecvMsg(m interface{}) error {
err := cs.ClientStream.RecvMsg(m)
if err == io.EOF {
// Consider the RPC as complete
return err
} else if err != nil {
// Consider the RPC as complete
return err
}
if !cs.isResponseStreaming {
// Consider the RPC as complete
}
return err
}
它在大多数情况下都有效,但我的理解是如果调用者知道结果将是 io.EOF
,则调用者不需要调用 Recv
(请参阅Are you required to call Recv until you get io.EOF when interacting with grpc.ClientStreams? ),所以它不会在所有情况下都有效。有没有更好的方法来实现这一目标?
最佳答案
我有一个非常相似的问题,我想跟踪流式 gRPC 调用。除了像你自己提到的那样装饰流,我无法找到检测流结束的好方法。也就是说,直到我遇到 grpc-go ( https://godoc.org/google.golang.org/grpc/stats ) 提供的统计 Hook 。尽管统计 API 旨在收集有关 RPC 调用的统计信息,但它提供的 Hook 对于跟踪也非常有帮助。
如果您仍在寻找跟踪流调用的方法,我已经使用统计 Hook 为 gRPC 的 OpenTracing 检测编写了一个库: https://github.com/charithe/otgrpc .但是,请记住,这种方法可能不适用于创建长生命周期流的系统。
关于go - 使用 StreamClientInterceptor 确定 RPC session 何时结束的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42988396/