duckrpc is a mini rpc framework for python
from duckrpc.duck_coder import DuckCoder
from duckrpc.duck_packet import DuckPacket
import json
class JsonCoder(DuckCoder):
def encode_packet(self, packet: DuckPacket) -> bytes:
return json.dumps(packet.__dict__).encode("utf-8")
def decode_packet(self, data: bytes) -> DuckPacket:
packet = DuckPacket()
packet.__dict__ = json.loads(data.decode("utf-8"))
return packet
from duckrpc.duck_factory import DuckSocketFactory
import socket
class SimpleSocketFactory(DuckSocketFactory):
def create(self) -> socket.socket:
return socket.socket()
def destroy(self, sock: socket.socket) -> None:
sock.close()
from duckrpc.duck_rpc_server import DuckRpcServerConfig, DuckRpcServer, DuckRpcBodyHandler
from duckrpc.duck_socket_event import DuckSocketEventDispatchConfig, EventDispatchMode
from duckrpc.duck_coder import DuckCoder
from duckrpc.duck_factory import DuckSocketFactory
class EchoHandler(DuckRpcBodyHandler):
def handle_body(self, body: any) -> any:
return body
bind_addr = "127.0.0.1"
bind_port = ...
backlog = 10
packet_dispatch_thread_size = 4
event_dispatch_thread_size = 4
coder: DuckCoder = ...
socket_factory: DuckSocketFactory = ...
config = DuckRpcServerConfig(
name="rpc-server",
bind_addr=bind_addr,
bind_port=bind_port,
backlog=backlog,
packet_dispatch_thread_size=packet_dispatch_thread_size,
coder=coder,
socket_factory=socket_factory
)
event_config = DuckSocketEventDispatchConfig(select_timeout=0.2,
dispatch_thread_size=event_dispatch_thread_size,
dispatch_mode=EventDispatchMode.THREAD)
rpc_server = DuckRpcServer(config=config, event_config=event_config, handler=EchoHandler())
rpc_server.start()
from duckrpc.duck_rpc_client import DuckRpcClientConfig, DuckRpcClient
from duckrpc.duck_coder import DuckCoder
from duckrpc.duck_factory import DuckSocketFactory
from duckrpc.duck_socket_event import DuckSocketEventDispatchConfig, EventDispatchMode
packet_dispatch_thread_size = 4
event_dispatch_thread_size = 4
coder: DuckCoder = ...
socket_factory: DuckSocketFactory = ...
remote_addr = ...
remote_port = ...
config: DuckRpcClientConfig = DuckRpcClientConfig(
name="rpc_client",
core_conn_size=1,
max_conn_size=1,
timeout_default=600,
remote_addr=remote_addr,
remote_port=remote_port,
packet_dispatch_thread_size=packet_dispatch_thread_size,
coder=coder,
socket_factory=socket_factory
)
event_config = DuckSocketEventDispatchConfig(select_timeout=0.1,
dispatch_thread_size=event_dispatch_thread_size,
dispatch_mode=EventDispatchMode.THREAD)
rpc_client = DuckRpcClient(config=config, event_config=event_config)
rpc_client = ...
req = ...
reply = rpc_client.rpc(req=...)
| ----------- | | -------------- | | ------------------------------------ |
| select loop | - dispatch - | event-dispatch | - read data(socket) - | packet-dispatch(handle body & reply) |
| ----------- | | -------------- | | ------------------------------------ |
see test_bench_rpc_server.py
------ bench mark info -------
event:8, packet:8, rpc:8
core_conn_size:8, max_conn_size: 8
total:10000, qps: 1182.4083359553138, avg:0.00675000057220459, max:0.12443304061889648, min:0.0029528141021728516