acktor_ipc/ipc_method.rs
1//! Traits for Inter-Process Communication (IPC) and some pre-implemented IPC methods.
2//!
3
4use std::io::Error;
5use std::pin::Pin;
6
7use bytes::Bytes;
8
9#[cfg(feature = "pipe")]
10#[cfg_attr(docsrs, doc(cfg(feature = "pipe")))]
11pub mod pipe;
12
13#[cfg(feature = "websocket")]
14#[cfg_attr(docsrs, doc(cfg(feature = "websocket")))]
15pub mod websocket;
16
17/// A boxed `Send` future returning `Result<T, IoError>`, used as the return type of
18/// dyn-compatible trait methods in this module.
19pub type IoFuture<'a, T> = Pin<Box<dyn Future<Output = Result<T, Error>> + Send + 'a>>;
20
21/// Describes the behavior of an IPC listener which accepts incoming IPC connections.
22///
23/// A [`Node`][crate::node::Node] uses a listener to accept inbound connections. Outbound
24/// connections are initiated by calling [`IpcConnection::connect`] on a concrete connection
25/// type directly.
26pub trait IpcListener: Send + Sync + 'static {
27 /// Returns the local endpoint the listener is bound to.
28 fn local_endpoint(&self) -> &str;
29
30 /// Accepts an incoming IPC connection.
31 ///
32 /// # Cancel safety
33 ///
34 /// This method is **not** guaranteed to be cancel safe. If the returned future is dropped
35 /// before it completes, it may leave a peer-side connection in a partially-initialized state
36 /// (e.g. mid-handshake).
37 fn accept(&self) -> IoFuture<'_, Box<dyn IpcConnection>>;
38}
39
40/// Describes the behavior of an IPC connection.
41///
42/// An IPC connection should be a duplex communication channel between two end points. If the
43/// underlying protocol is not duplex, the implementation should simulate the duplex behavior,
44/// e.g., by using two separate connections.
45///
46/// Implementations are responsible for message framing: one call to [`send`](Self::send) must
47/// correspond to exactly one call to [`recv`](Self::recv) on the remote end, regardless of how
48/// the underlying transport delivers bytes.
49pub trait IpcConnection: Send + Sync + 'static {
50 /// Connects to an IPC listener at a specific endpoint.
51 ///
52 /// This is a constructor-style method that returns a concrete connection, so it requires
53 /// `Self: Sized`.
54 fn connect(endpoint: &str) -> impl Future<Output = Result<Self, Error>> + Send
55 where
56 Self: Sized;
57
58 /// Returns the peer endpoint of the IPC connection.
59 fn peer_endpoint(&self) -> &str;
60
61 /// Closes the IPC connection.
62 fn close(&mut self) -> IoFuture<'_, ()>;
63
64 /// Sends a message to the other end of the connection.
65 ///
66 /// The entire `buf` is delivered as a single framed message.
67 fn send(&mut self, buf: Bytes) -> IoFuture<'_, ()>;
68
69 /// Receives the next message from the other end of the connection.
70 ///
71 /// Returns the message payload as a [`Bytes`] value; implementations should return a slice
72 /// of their internal read buffer whenever possible to avoid copying.
73 ///
74 /// # Cancel safety
75 ///
76 /// The implementation should be cancel safe. If the method is used as the event in a
77 /// [`tokio::select!`](tokio::select) statement and some other branch completes first, then
78 /// it is guaranteed that no data was read from the underlying connection.
79 fn recv(&mut self) -> IoFuture<'_, Bytes>;
80}