def worker(*, uid: int, endpoint: str): ctx = zmq.Context() dispatcher = RPCDispatcher() client = RPCClient( JSONRPCProtocol(), ZmqClientTransport.create(ctx, endpoint), ) proxy = client.get_proxy() @dispatcher.public def do_task(): from time import sleep for i in range(5): proxy.notify(f"{uid} y{i} ") sleep(0.1) return f"OK {uid}" @dispatcher.public def exit(): proxy.exit(uid) transport = ZmqServerTransport.create( ctx, endpoint.replace(".manager", f".{uid}")) rpc_server = RPCServer(transport, JSONRPCProtocol(), dispatcher) rpc_server.trace = partial(print, file=sys.stderr) rpc_server.serve_forever()
def client(*, endpoint: str, callback_endpoint: str): ctx = zmq.Context() dispatcher = RPCDispatcher() @dispatcher.public def notify(s: str): print("** {s} **") callback_server = RPCServer( ZmqServerTransport.create(ctx, callback_endpoint), JSONRPCProtocol(), dispatcher) callback_server.trace = print threading.Thread(target=callback_server.serve_forever, daemon=True).start() rpc_client = RPCClient(JSONRPCProtocol(), ZmqClientTransport.create(ctx, endpoint)) remote_server = rpc_client.get_proxy() for i in range(7): result = remote_server.act(i, "Hello, World!") print("Server answered:", result) result = remote_server.shutdown() print("Send shutdown:", result)
def test_handle_message_callback(transport, protocol, dispatcher): server = RPCServer(transport, protocol, dispatcher) server.trace = Mock(return_value=None) server.receive_one_message() assert server.trace.call_args_list == [call('-->', CONTEXT, RECMSG), call('<--', CONTEXT, SERMSG)] server.trace.assert_called()
def test_handle_message_callback(transport, protocol, dispatcher): server = RPCServer(transport, protocol, dispatcher) server.trace = Mock(return_value=None) server.receive_one_message() assert server.trace.call_args_list == [ call('-->', CONTEXT, RECMSG), call('<--', CONTEXT, SERMSG) ] server.trace.assert_called()
def worker(): rpc_server = RPCServer( SubprocessServerTransport( input_port=sys.stdin.buffer, output_port=sys.stdout.buffer ), JSONRPCProtocol(), dispatcher, ) rpc_server.trace = partial(print, file=sys.stderr) rpc_server.serve_forever()
class CallbackServerTransport(ServerTransport): def receive_message(self) -> t.Tuple[t.Any, bytes]: context = "*context*" return context, in_box.pop(0) def send_reply(self, context: t.Any, reply: bytes): print(context) out_box.append(reply) rpc_server = RPCServer( CallbackServerTransport(), JSONRPCProtocol(), dispatcher, ) rpc_server.trace = print # 本来はこれを実行する # rpc_server.serve_forever() rpc_client = RPCClient(JSONRPCProtocol(), CallbackClientTransport()) proxy = rpc_client.get_proxy() try: result = proxy.add(10, 20) print(f"result is {result}") except Exception as e: print(e)
def server(*, endpoint: str): import queue import threading import time from concurrent.futures import Future from tinyrpc.transports.zmq import ZmqServerTransport from tinyrpc.server import RPCServer from tinyrpc.dispatch import RPCDispatcher q = queue.Queue() ev = threading.Event() ctx = zmq.Context() dispatcher = RPCDispatcher() transport = ZmqServerTransport.create(ctx, endpoint) rpc_server = RPCServer(transport, JSONRPCProtocol(), dispatcher) rpc_server.trace = print running = True @dispatcher.public def act(uid: int, s: str) -> str: q.put(("act", (uid, s), {})) ev.set() return "ok" @dispatcher.public def shutdown() -> None: nonlocal running running = False def do_act(uid: int, s: str) -> Future: fut = Future() def do(): for i in range(5): print(f"{uid:02d}: {i} {s}") time.sleep(0.1) fut.set_result(("ok", uid)) threading.Thread(target=do, daemon=True).start() return fut def do_server(): nonlocal running while running: rpc_server.receive_one_message() def do_loop(*, ns): nonlocal running while running: fn, args, kwargs = q.get() fut = ns[f"do_{fn}"](*args, **kwargs) def cont(fut): q.task_done() fut.add_done_callback(cont) ns = locals() th = threading.Thread(target=do_loop, kwargs={"ns": ns}, daemon=True) th.start() th2 = threading.Thread(target=do_server, daemon=True) th2.start() ev.wait() q.join()
def server(*, endpoint: str, callback_endpoint: str): q = queue.Queue() ev = threading.Event() ctx = zmq.Context() dispatcher = RPCDispatcher() rpc_server = RPCServer(ZmqServerTransport.create(ctx, endpoint), JSONRPCProtocol(), dispatcher) rpc_server.trace = print # client callback_client = RPCClient( JSONRPCProtocol(), ZmqClientTransport.create(ctx, callback_endpoint)) callback_remote_server = callback_client.get_proxy(one_way=True) running = True @dispatcher.public def act(uid: int, s: str) -> str: q.put(("act", (uid, s), {})) ev.set() return "ok" @dispatcher.public def shutdown() -> None: nonlocal running running = False def do_act(uid: int, s: str) -> Future: fut = Future() def do(): for i in range(5): callback_remote_server.notify(f"{uid:02d}: {i} {s}") print(f"{uid:02d}: {i} {s}") time.sleep(0.1) fut.set_result(("ok", uid)) threading.Thread(target=do, daemon=True).start() return fut def do_server(): nonlocal running while running: rpc_server.receive_one_message() def do_loop(*, ns): nonlocal running while running: fn, args, kwargs = q.get() fut = ns[f"do_{fn}"](*args, **kwargs) def cont(fut): q.task_done() fut.add_done_callback(cont) ns = locals() th = threading.Thread(target=do_loop, kwargs={"ns": ns}, daemon=True) th.start() th2 = threading.Thread(target=do_server, daemon=True) th2.start() ev.wait() q.join()