web-dev-qa-db-ja.com

PythonのgRPCライブラリでタイムアウトをどのように設定しますか

私はgrpcサーバー/クライアントを持っていますが、今日は時々ハングして問題を引き起こします。これは、バックグラウンドワーカープロセスにチェックインして動作している/機能していることを確認するFlaskアプリケーションから呼び出されています。gRPCサーバーにリクエストを送信するには、次のようにします。

try:
        health = self.grpc_client.Health(self.health_ping)
        if health.message == u'PONG':
            return {
                u'healthy': True,
                u'message': {
                    u'healthy': True,
                    u'message': u'success'
                },
                u'status_code': 200
            }
except Exception as e:
        if str(e.code()) == u'StatusCode.UNAVAILABLE':
            return {
                u'healthy': False,
                u'message': {
                    u'healthy': False,
                    u'message': (u'[503 Unavailable] connection to worker '
                                 u'failed')},
                u'status_code': 200}
        Elif str(e.code()) == u'StatusCode.INTERNAL':
            return {
                u'healthy': False,
                u'message': {
                    u'healthy': False,
                    u'message': (u'[500 Internal] worker encountered '
                                 u'an error while responding')},
                u'status_code': 200}
        return {
            u'healthy': False,
            u'message': {u'healthy': False, u'message': e.message},
            u'status_code': 500
        }

クライアントはスタブです:

channel = grpc.insecure_channel(address)
stub = WorkerStub(channel)
return stub

プロトは:

syntax = "proto3";

option Java_multiple_files = true;
option Java_package = "com.company.project.worker";
option Java_outer_classname = "ProjectWorker";
option objc_class_prefix = "PJW";

package projectworker;

service Worker {
  rpc Health (Ping) returns (Pong) {}
}

// The request message containing PONG
message Ping {
  string message = 1;
}

// The response message containing PONG
message Pong {
  string message = 1;
}

このコードを使用して、タイムアウトを追加して、失敗してハングするのではなく、常に応答できるようにするにはどうすればよいですか?

6
kkirsche

timeoutはRPC呼び出しのオプションのキーワードパラメータです 変更する必要があります

health = self.grpc_client.Health(self.health_ping)

health = self.grpc_client.Health(self.health_ping, timeout=my_timeout_in_seconds)

また、他のエラーとは異なる方法でタイムアウトをキャッチして処理することもできます。残念ながら、このトピックに関するドキュメントはあまり良くないので、次のようになります。

try:
    health = self.grpc_client.Health(self.health_ping, timeout=my_timeout_in_seconds)
except grpc.RpcError as e:
    e.details()
    status_code = e.code()
    status_code.name
    status_code.value

タイムアウトはDEADLINE_EXCEEDEDstatus_code.valueを返します。

1
user582175

クライアント側でタイムアウトを定義するには、サービス関数を呼び出すときにオプションのパラメーターtimeout=<timeout in seconds>を追加します。

channel = grpc.insecure_channel(...)
stub = my_service_pb2_grpc.MyServiceStub(channel)
request = my_service_pb2.DoSomethingRequest(data='this is my data')
response = stub.DoSomething(request, timeout=0.5)

????タイムアウトの状況では例外が発生することに注意してください

0
Jossef Harush