Skip to content

How to write it: RPC client with out of order responses #369

@bluetech

Description

@bluetech

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions