チャットのようなアプリケーションを作成したいとしましょう。クライアントはテキストをサーバーに送信することができ、その逆もあります。テキスト交換の順序は任意です。GRPCストリーミングセレクト(Python)
サーバーは、サーバーの応答ストリームを制御する別のストリームに依存します。 GRPCストリームはPythonジェネレータとして公開されています。サーバーは、クライアントの入力と同時に他のストリームの入力を待つことができますか?通常はselect()のようなものを使用しますが、ここではジェネレータがあります。
私は、望ましい動作を実装するいくつかのサンプルコードを持っていますが、クライアントとサーバー側に追加のスレッドが必要です。スレッドなしで同じ結果を得るにはどうすればよいですか?
プロト:
syntax = 'proto3';
service Scenario {
rpc Chat(stream DPong) returns (stream DPong) {}
}
message DPong {
string name = 1;
}
サーバー:
import random
import string
import threading
import grpc
import scenario_pb2_grpc
import scenario_pb2
import time
from concurrent import futures
class Scenario(scenario_pb2_grpc.ScenarioServicer):
def Chat(self, request_iterator, context):
def stream():
while 1:
time.sleep(1)
yield random.choice(string.ascii_letters)
output_stream = stream()
def read_incoming():
while 1:
received = next(request_iterator)
print('received: {}'.format(received))
thread = threading.Thread(target=read_incoming)
thread.daemon = True
thread.start()
while 1:
yield scenario_pb2.DPong(name=next(output_stream))
if __name__ == '__main__':
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
scenario_pb2.add_ScenarioServicer_to_server(
Scenario(), server)
server.add_insecure_port('[::]:50052')
server.start()
print('listening ...')
while 1:
time.sleep(1)
クライアント
import threading
import grpc
import time
import scenario_pb2_grpc, scenario_pb2
def run():
channel = grpc.insecure_channel('localhost:50052')
stub = scenario_pb2_grpc.ScenarioStub(channel)
print('client connected')
def stream():
while 1:
yield scenario_pb2.DPong(name=input('$ '))
input_stream = stub.Chat(stream())
def read_incoming():
while 1:
print('received: {}'.format(next(input_stream).name))
thread = threading.Thread(target=read_incoming)
thread.daemon = True
thread.start()
while 1:
time.sleep(1)
if __name__ == '__main__':
print('client starting ...')
run()
余分なスレッドがアプリケーションにどれくらいのコストをかけているかを説明できますか? –