StreamClientInterceptor関数を記述するとき、呼び出し元がRPCを終了したときを判断する最善の方法は何ですか?これは、単なるインターセプタやRPCを実行するhandlerが渡されたサーバ側では簡単ですが、クライアント側でClientStreamを返すクライアント側でこれを行う最良の方法が不明です。StreamClientInterceptorを使用してRPCセッションが終了するときを判断する最善の方法は何ですか?
この用途の1つの用途は、OpenTracingをインストルメントすることです。ここでの目的は、RPCの開始と終了を示すスパンを開始および終了することです。
私が検討している戦略は、ストリームインターセプタがデコレートされたClientStreamを返すことです。この新しいClientStreamは、インターフェイスメソッドHeader
,CloseSend
、SendMsg
、RecvMsg
のいずれかがエラーを返した場合、またはContext
がキャンセルされた場合にRPCが完了したとみなします。さらに、それは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
になります知っている場合(Are you required to call Recv until you get io.EOF when interacting with grpc.ClientStreams?を参照)Recv
を呼び出すために必要とされていないということです、すべての場合にうまくいくわけではありません。これを達成するより良い方法はありますか?