dcl_rpc/transports/memory.rs
1//! MemoryTransport has no common use case in a server or web app but it's great for testing propouses.
2//!
3//! However, this type of transport has an use case on Decentraland for the comms between `Scenes<>BrowserInterface<>GameEngine`.
4//!
5//! The most common use case is for testing. It uses [`async_channel`] internally
6use super::{Transport, TransportError, TransportMessage};
7use async_channel::{bounded, Receiver, Sender};
8use async_trait::async_trait;
9
10/// Using channels for the communication between a `RpcClient` and `RpcServer` running on the same process.
11pub struct MemoryTransport {
12 /// The sender half of an [`async_channel::bounded`] channel
13 ///
14 /// It uses an [`async_channel`] to meet the requirements of the [`Transport`] trait
15 ///
16 /// eg: [`RpcClient`](crate::client::RpcClient) stores the sender half of the channel which the [`RpcServer`](crate::server::RpcServer) stores the receiver half and viceversa
17 sender: Sender<Vec<u8>>,
18 /// The receiver half of an [`async_channel::bounded`] channel
19 ///
20 /// It uses an [`async_channel`] to meet the requirements of the [`Transport`] trait
21 ///
22 /// eg: [`RpcClient`](crate::client::RpcClient) stores the receiver half of the channel which the [`RpcServer`](crate::server::RpcServer) stores the sender half and viceversa
23 receiver: Receiver<Vec<u8>>,
24}
25
26impl MemoryTransport {
27 fn new(sender: Sender<Vec<u8>>, receiver: Receiver<Vec<u8>>) -> Self {
28 Self { sender, receiver }
29 }
30
31 /// It creates two [`MemoryTransport`]s for the both ends using [`async_channel::bounded`]
32 ///
33 /// The first element in the tuple is the transport for the [`RpcClient`](crate::client::RpcClient) and the second one for the [`RpcServer`](crate::server::RpcServer)
34 pub fn create() -> (Self, Self) {
35 let (client_sender, server_receiver) = bounded::<Vec<u8>>(32);
36 let (server_sender, client_receiver) = bounded::<Vec<u8>>(32);
37
38 let client = Self::new(client_sender, client_receiver);
39 let server = Self::new(server_sender, server_receiver);
40
41 (client, server)
42 }
43}
44
45#[async_trait]
46impl Transport for MemoryTransport {
47 async fn receive(&self) -> Result<TransportMessage, TransportError> {
48 match self.receiver.recv().await {
49 Ok(message) => Ok(message),
50 Err(_) => {
51 self.close().await;
52 Err(TransportError::Closed)
53 }
54 }
55 }
56
57 async fn send(&self, message: Vec<u8>) -> Result<(), TransportError> {
58 match self.sender.send(message).await {
59 Ok(_) => Ok(()),
60 Err(_) => Err(TransportError::Closed),
61 }
62 }
63
64 async fn close(&self) {
65 self.receiver.close();
66 }
67}