web-dev-qa-db-ja.com

GRPCサーバーに接続されているクライアントを検査する方法

GRPCサーバー/クライアントセットアップのより良いデバッグ情報を提供するために、サーバーに接続されているクライアントを検査できる_grpc.server_のAPIを見つけようとしています。

私が見つけた最も有望な質問は 質問です。これは、Java GRPC でこれを行う方法の出発点を与えます。しかし、Java APIはPython GRPC実装には存在しません。

これまでのところ、_grpc.ServicerContext_のcontext.peer()メソッドを使用して一意のピアを追跡しています。ピアがしばらくリクエストを送信しなかった場合(タイムアウトを2秒に設定)、クライアントが切断されたと想定します。

Python-grpcのソースコードを調べ始めましたが、まだ進んでいません。

pythonで使用できる類似のAPIを知っている人がいれば、それはありがたいです!これらのデバッグのニーズには内部APIでも十分です。

7
pmelanson

私はさらにいくつかのドキュメントとchannelzの例を見つけました、他の人々がそれを提案していて、それはあなたが望んでいるようです。

これが 使用されているchannelzの例を示すプルリクエスト です。 GetServer channelz APIのみを使用するため、適応させる必要があります。

そして、ここに channelzを使用する単体テスト があります。これは、おそらくGetTopChannels APIに関連するAPIをテストします。

1
trainer-blue

これにはネイティブAPIはありませんが、必要なものはすべて揃っています。以下は、リポジトリのhelloworldの例の修正版です。

class PeerSet(object):
    def __init__(self):
        self._peers_lock = threading.RLock()
        self._peers = {}

    def connect(self, peer):
        print("Peer {} connecting".format(peer))
        with self._peers_lock:
            if peer not in self._peers:
                self._peers[peer] = 1
            else:
                self._peers[peer] += 1

    def disconnect(self, peer):
        print("Peer {} disconnecting".format(peer))
        with self._peers_lock:
            if peer not in self._peers:
                raise RuntimeError("Tried to disconnect peer '{}' but it was never connected.".format(peer))
            self._peers[peer] -= 1
            if self._peers[peer] == 0:
                del self._peers[peer]

    def peers(self):
        with self._peers_lock:
            return self._peers.keys()


class Greeter(helloworld_pb2_grpc.GreeterServicer):

    def __init__(self):
        self._peer_set = PeerSet()

    def _record_peer(self, context):
        def _unregister_peer():
            self._peer_set.disconnect(context.peer())
        context.add_callback(_unregister_peer)
        self._peer_set.connect(context.peer())

    def SayHello(self, request, context):
        self._record_peer(context)
        for i in range(10):
            print("[thread {}] Peers: {}".format(threading.currentThread().ident, self._peer_set.peers()))
            time.sleep(1)
        return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)

これにより、次のような出力が得られます。

[thread 139905506195200] Peers: [u'ipv6:[::1]:57940', u'ipv6:[::1]:57930', u'ipv6:[::1]:57926', u'ipv6:[::1]:57920', u'ipv6:[::1]:57934']

Dingが上でコメントしたように、 channelz も適しています。

1