tosc-rs / mgnp

MnemOS Global Networking Protocol
Creative Commons Attribution Share Alike 4.0 International
14 stars 1 forks source link

design for request-response protocols #25

Closed hawkw closed 8 months ago

hawkw commented 8 months ago

MGNP itself is not a request-response protocol; MGNP connections are bidirectionally streaming. however, it is possible to implement a request-response protocol on top of a bidirectional-streaming protocol.

"synchronous request-response" protocols like HTTP/1, where a single request is in flight over a given connection at any time, can be implemented quite simply on top of a bidi stream. you simply say that once the server receives a request message on a given connection, the next message will be a server-sent response, and the client must not send another request until it has received the server's response.

however, it is also possible to use a bidirectional streaming protocol to implement an "asynchronous request-response" protocol. this is a protocol like HTTP/2, where multiple requests can be in flight over the same connection, and the server may not respond to all those requests in the same order as they were sent. this can be implemented by sending a sequence number/request identifier as part of the request message, and having the response message contain that sequence number to indicate which request it was in response to.

this also allows unidirectional streaming request/response protocols, where a request or response may consist of multiple messages with the same identifier. for example, a client might send a request for streaming data with a request ID, and then the server sends back a bunch of messages with the same request ID.

none of this needs to be part of the MGNP core protocol and can be implemented in the application layer. however, it would be kind of cool if the MGNP library could provide utilities to make it easier to transport this kind of protocols over MGNP. for example, maybe we could have something like this:

pub trait ReqRspService {
    type Req;
    type Rsp;
}

impl<S: ReqRspService> Service for S {
   type ClientMsg = Request<S::Req>;
   type ServerMsg = Response<S::Rsp>;
   // ...
}

and then provide APIs for automatically implementing the request/response correlation IDs for a ReqRspService.

this is out of scope for MGNP v0.1, since it isn't part of the core protocol and can always be implemented in user code. But, it would be cool to have eventually...