Description
I’m looking at using KRPC to reimplement an RPC interface previously implemented with CapnProto. The limitation I’m running into is that calls can be made in only one direction: one peer is the “client” and can make calls, the other is the “server” and can only receive and reply to calls. The interface I’m using is symmetrical: both sides can send requests to the other.
(This interface is for a form of data sync involving hash trees; it involves a sequence of negotiations where the ‘client’ side requests information about a tree node, examines it, and as a result may need to request more information or [recursively] send requests for child nodes. To enable bidirectional sync, both sides of a connection need to be able to adopt either the server or client role.)
Issue #238 describes a similar use case, and the (unofficial) answer was "I think the intended solution for server->client communication is flows.” This does make sense for a specific type of server-to-client communication, a “push” model where the server just sends notifications. But it doesn’t suffice when the server needs responses to the messages it sends.
To do the server-to-client communication with a flow would involve an implementation like:
- Client initiates sending an RPC request that the server responds to with a flow.
- When the server needs to request, it sends an object over the flow that contains a request-type enum and arguments, as well as some unique request ID generated by a counter
- The client receives the request from the flow, dispatches it according to the ‘type’ field, and processes it.
- The client sends the response by sending another RPC request, passing the server’s request ID.
- The server’s RPC implementation looks up the request ID in a table of pending requests, and pass the args to whoever’s waiting for it.
This really looks like it’s artificially re-inventing a lot of what’s going on inside KRPC. It would be so much simpler if KRPC were symmetrical, so the client could register its own service and the server could access a client implementation of it.