2018年2月25日日曜日

gRPC の非同期メソッドのステータスは一度しか取得できない 3/3 訂正調査中

gRPC のストリーミング通信のステータスを取得する GetStatus メソッドは一度しか呼び出せません。一度しか呼び出さないように注意すればよいだけのですが、ラッパーや拡張メソッド形式の汎用処理を実装するときに少しはまりました。



2018/03/03
一回しか取得できないというのはどうやら間違いです。再調査しています。
"once" という単語を誤って解釈してしまったようです。

ステータスの取得方法


AsyncDuplexStreamingCall<TRequest, TResponse> クラスなど非同期メソッドの戻り値型にはステータスを取得するための GeStatus メソッドが実装されています。このメソッドからステータスを取得することができます。


完了していないと例外が発生


GetStatus メソッドには制約があり、非同期メソッドの処理が完了していないと InvalidOperationException 例外が発生します。ソースコードの XML コメントにも次のように記載されています。

Gets the call status if the call has already finished. Throws InvalidOperationException otherwise.

非同期メソッドの処理の完了を待ってから GetStatus メソッドを呼び出せばよいのですが、AsyncDuplexStreamingCall<TRequest, TResponse> クラスには処理が完了したかどうかを表すようなプロパティがありません。ResponseHeadersAsync プロパティの IsCompleted プロパティが true かどうかで判断することにしました。


二回呼び出すと例外が発生


もう一つの制約は、二回以上呼び出すと InvalidOperationException 例外が発生するということです。こちらについては XML コメントには記載されていません。

Status can only be accessed once the call has finished.

既に呼び出したかどうかを知るためのプロパティはありません。ステータスに応じた汎用処理を実装しようとした場合、その中で GetStatus メソッドを一回呼び出すことになります。その後、アプリケーションコードでもう一度 GetStatus メソッドを呼び出すと例外が発生します。

アプリケーションコードでは呼び出さないようにするルールを設けてもそれが遵守されるかどうかは保証されません。ラッパークラスを使用するなどし、GetStatus メソッドの呼び出しを制御するような仕組みを考えたほうがよさそうです。



トレーラーも同じ


トレーラーを取得する GetTrailers メソッドも同じです。

0 件のコメント:

コメントを投稿

paiza のスキルチェックをやってみました

いまさら感はありますが、 paiza のスキルチェックをやってみました。指定された時間内にコードを書いてユニットテストにかけ、その結果を基に評価を数値化してくれるというものですが、ゲーム感覚で空き時間を見つけて進めていこうと考えています。 どうやら時間が短いほど高い評価を得...