Module strymon_communication::rpc
[−]
[src]
Asynchronous remote procedure calls.
This implements a small framework for receiving and sending requests and responses between two connected peers. During set-up, one of the peers acts as a server, listening on a server socket to accept new incoming clients. Clients connect to a server using the socket address.
Once a connection between two peers is established, their initial role as server and client becomes irrelevant, as they take on the role of either being a sender or receiver (or both) of requests.
1. Defining a custom protocol
In order to use this framework, client code must first define the types
to be used for a request-response protocol. It is not using a custom
interface description language (IDL) but rather is based on implementing
certain Rust traits. Different types of requests must be distinguished
from each other through a value called the name (i.e. the name of the
remote procedure). Since the name is typically used for dispatching on the
receiver-side, it is recommended to use an enum
for it.
The name, argument and return types of a method are defined by implementing
the Request
type. Each invocation can either return
successfully with the type specified in
Request::Success
or fail with
an application-specific error defined in
Request::Error
.
2. Connection set-up
During connection set-up, one peer needs to act as a server. To instantiate
a server, invoke Network::server()
to obtain a handle for new incoming clients.
The client is expected to call
Network::client()
with the
corresponding socket address to connect to the server. Both peers will
obtain a pair of
(Incoming
, Outgoing
)
queue handles. These are used to either receive incoming requests, or
send out outgoing requests.
3. Handling requests & responses
Once connected, a peer might decide to send requests by invoking
Outgoing::request()
with an
argument implementing the Request
trait. The
remote peer will receive this request on its
Incoming
queue in the form of an encoded
RequestBuf
object. To decode this object, it
is common to match on the method name returned by
RequestBuf::name()
and then decode
the request payload using
RequestBuf::decode()
. Decoding
a request successfully returns the decoded payload, as well as a
Responder
object which is used to send back the
response to the origin.
Once the response arrives back at the original sender, the
Response
future will resolve to the decoded
response.
Examples:
Please refer to tests/calc.rs
for a complete example of how to use
this module.
Structs
Incoming |
Receiver-side queue of incoming requests. |
Outgoing |
Sender-side queue for sending out requests. |
RequestBuf |
Receiver-side buffer containing an incoming request. |
Responder |
Receiver-side handle for responding to a given request. |
Response |
Sender-side future eventually yielding the response for a request. |
Server |
Handle for queue of newly connected peers. |
Traits
Name |
A trait to distinguish remote procedure calls. |
Request |
A trait for defining the signature of a remote procedure. |