-
-
Notifications
You must be signed in to change notification settings - Fork 362
Description
This is a fun little problem and I was wondering what is the best way to use trio to solve it. I hope this is appropriate here.
Consider a simple RPC protocol:
Example request: {"id": 15353, "params": ...}
Example successful response: {"id": 15353, "result": ...}
Example error response: {"id": 15353, "error": ...}
The client can send multiple requests concurrently. The server can respond out of order.
Suppose we want to write a client for this protocol using trio. We want to send many concurrent requests and handle their responses. We want to have a synchronous-looking API, e.g. try { response = await send(request) } except { ... }
.
Here is how I would solve it (I've hidden it in case someone wants to come up with an independent solution 💭):
-
Add a future/promise abstraction using
trio.Event
internally. Curio has a simple one. -
The sending function creates a future, stores it in a
request id -> future
dict, sends the request, and waits on the future. -
Spawn a received task which receives responses from the server and sets the result/exception on the corresponding future in the
request id -> future
dict. -
For each request, spawn a task which would use the sending function.
Is there a more elegant way?