Skip to main content

memberlist_core/transport/
stream.rs

1use async_channel::{Receiver, Sender};
2pub use async_channel::{RecvError, SendError, TryRecvError, TrySendError};
3use futures::Stream;
4
5use super::*;
6
7/// The packet receives from the unreliable connection.
8#[viewit::viewit(
9  vis_all = "",
10  getters(vis_all = "pub", style = "ref"),
11  setters(vis_all = "pub", prefix = "with")
12)]
13#[derive(Debug, Clone, PartialEq, Eq, Hash)]
14pub struct Packet<A, T> {
15  /// The raw contents of the packet.
16  #[viewit(
17    getter(
18      const,
19      style = "ref",
20      attrs(doc = "Returns the messages of the packet")
21    ),
22    setter(attrs(doc = "Sets the messages of the packet (Builder pattern)"))
23  )]
24  payload: Bytes,
25
26  /// Address of the peer. This is an actual address so we
27  /// can expose some concrete details about incoming packets.
28  #[viewit(
29    getter(
30      const,
31      style = "ref",
32      attrs(doc = "Returns the address sent the packet")
33    ),
34    setter(attrs(doc = "Sets the address who sent the packet (Builder pattern)"))
35  )]
36  from: A,
37
38  /// The time when the packet was received. This should be
39  /// taken as close as possible to the actual receipt time to help make an
40  /// accurate RTT measurement during probes.
41  #[viewit(
42    getter(
43      const,
44      style = "ref",
45      attrs(doc = "Returns the instant when the packet was received")
46    ),
47    setter(attrs(doc = "Sets the instant when the packet was received (Builder pattern)"))
48  )]
49  timestamp: T,
50}
51
52impl<A, T> Packet<A, T> {
53  /// Create a new packet
54  #[inline]
55  pub const fn new(from: A, timestamp: T, payload: Bytes) -> Self {
56    Self {
57      payload,
58      from,
59      timestamp,
60    }
61  }
62
63  /// Returns the raw contents of the packet.
64  #[inline]
65  pub fn into_components(self) -> (A, T, Bytes) {
66    (self.from, self.timestamp, self.payload)
67  }
68
69  /// Sets the address who sent the packet
70  #[inline]
71  pub fn set_from(&mut self, from: A) -> &mut Self {
72    self.from = from;
73    self
74  }
75
76  /// Sets the instant when the packet was received
77  #[inline]
78  pub fn set_timestamp(&mut self, timestamp: T) -> &mut Self {
79    self.timestamp = timestamp;
80    self
81  }
82
83  /// Sets the payload of the packet
84  #[inline]
85  pub fn set_payload(&mut self, payload: Bytes) -> &mut Self {
86    self.payload = payload;
87    self
88  }
89}
90
91/// A producer for packets.
92#[derive(Debug, Clone)]
93#[repr(transparent)]
94pub struct PacketProducer<A, T> {
95  sender: Sender<Packet<A, T>>,
96}
97
98/// A subscriber for packets.
99#[pin_project::pin_project]
100#[derive(Debug, Clone)]
101#[repr(transparent)]
102pub struct PacketSubscriber<A, T> {
103  #[pin]
104  receiver: Receiver<Packet<A, T>>,
105}
106
107/// Returns producer and subscriber for packet.
108pub fn packet_stream<T: Transport>(capacity: usize) -> (
109  PacketProducer<T::ResolvedAddress, <T::Runtime as RuntimeLite>::Instant>,
110  PacketSubscriber<T::ResolvedAddress, <T::Runtime as RuntimeLite>::Instant>,
111) {
112  let (sender, receiver) = async_channel::bounded(capacity);
113  (PacketProducer { sender }, PacketSubscriber { receiver })
114}
115
116impl<A, T> PacketProducer<A, T> {
117  /// Sends a packet into the producer.
118  ///
119  /// If the producer is full, this method waits until there is space for a message.
120  ///
121  /// If the producer is closed, this method returns an error.
122  pub async fn send(&self, packet: Packet<A, T>) -> Result<(), SendError<Packet<A, T>>> {
123    self.sender.send(packet).await
124  }
125
126  /// Attempts to send a packet into the producer.
127  ///
128  /// If the channel is full or closed, this method returns an error.
129  pub fn try_send(&self, packet: Packet<A, T>) -> Result<(), TrySendError<Packet<A, T>>> {
130    self.sender.try_send(packet)
131  }
132
133  /// Returns `true` if the producer is empty.
134  pub fn is_empty(&self) -> bool {
135    self.sender.is_empty()
136  }
137
138  /// Returns the number of packets in the producer.
139  pub fn len(&self) -> usize {
140    self.sender.len()
141  }
142
143  /// Returns `true` if the producer is full.
144  pub fn is_full(&self) -> bool {
145    self.sender.is_full()
146  }
147
148  /// Returns `true` if the producer is closed.
149  pub fn is_closed(&self) -> bool {
150    self.sender.is_closed()
151  }
152
153  /// Closes the producer. Returns `true` if the producer was closed by this call.
154  pub fn close(&self) -> bool {
155    self.sender.close()
156  }
157}
158
159impl<A, T> PacketSubscriber<A, T> {
160  /// Receives a packet from the subscriber.
161  ///
162  /// If the subscriber is empty, this method waits until there is a message.
163  ///
164  /// If the subscriber is closed, this method receives a message or returns an error if there are
165  /// no more messages.
166  pub async fn recv(&self) -> Result<Packet<A, T>, RecvError> {
167    self.receiver.recv().await
168  }
169
170  /// Attempts to receive a message from the subscriber.
171  ///
172  /// If the subscriber is empty, or empty and closed, this method returns an error.
173  pub fn try_recv(&self) -> Result<Packet<A, T>, TryRecvError> {
174    self.receiver.try_recv()
175  }
176
177  /// Returns `true` if the subscriber is empty.
178  pub fn is_empty(&self) -> bool {
179    self.receiver.is_empty()
180  }
181
182  /// Returns the number of packets in the subscriber.
183  pub fn len(&self) -> usize {
184    self.receiver.len()
185  }
186
187  /// Returns `true` if the subscriber is full.
188  pub fn is_full(&self) -> bool {
189    self.receiver.is_full()
190  }
191
192  /// Returns `true` if the subscriber is closed.
193  pub fn is_closed(&self) -> bool {
194    self.receiver.is_closed()
195  }
196
197  /// Closes the subscriber. Returns `true` if the subscriber was closed by this call.
198  pub fn close(&self) -> bool {
199    self.receiver.close()
200  }
201}
202
203impl<A, T> Stream for PacketSubscriber<A, T> {
204  type Item = <Receiver<Packet<A, T>> as Stream>::Item;
205
206  fn poll_next(
207    self: std::pin::Pin<&mut Self>,
208    cx: &mut std::task::Context<'_>,
209  ) -> std::task::Poll<Option<Self::Item>> {
210    <Receiver<_> as Stream>::poll_next(self.project().receiver, cx)
211  }
212}
213
214/// Returns producer and subscriber for promised stream.
215pub fn promised_stream<T: Transport>() -> (
216  StreamProducer<T::ResolvedAddress, T::Connection>,
217  StreamSubscriber<T::ResolvedAddress, T::Connection>,
218) {
219  let (sender, receiver) = async_channel::bounded(1);
220  (StreamProducer { sender }, StreamSubscriber { receiver })
221}
222
223/// A producer for promised streams.
224#[derive(Debug)]
225#[repr(transparent)]
226pub struct StreamProducer<A, S> {
227  sender: Sender<(A, S)>,
228}
229
230impl<A, S> Clone for StreamProducer<A, S> {
231  fn clone(&self) -> Self {
232    Self {
233      sender: self.sender.clone(),
234    }
235  }
236}
237
238/// A subscriber for promised streams.
239#[pin_project::pin_project]
240#[derive(Debug)]
241#[repr(transparent)]
242pub struct StreamSubscriber<A, S> {
243  #[pin]
244  receiver: Receiver<(A, S)>,
245}
246
247impl<A, S> Clone for StreamSubscriber<A, S> {
248  fn clone(&self) -> Self {
249    Self {
250      receiver: self.receiver.clone(),
251    }
252  }
253}
254
255impl<A, S> StreamProducer<A, S> {
256  /// Sends a promised stream into the producer.
257  ///
258  /// If the producer is full, this method waits until there is space for a stream.
259  ///
260  /// If the producer is closed, this method returns an error.
261  pub async fn send(&self, addr: A, conn: S) -> Result<(), SendError<(A, S)>> {
262    self.sender.send((addr, conn)).await
263  }
264
265  /// Attempts to send a promised stream into the producer.
266  ///
267  /// If the producer is full or closed, this method returns an error.
268  pub fn try_send(&self, addr: A, conn: S) -> Result<(), TrySendError<(A, S)>> {
269    self.sender.try_send((addr, conn))
270  }
271
272  /// Returns `true` if the producer is empty.
273  pub fn is_empty(&self) -> bool {
274    self.sender.is_empty()
275  }
276
277  /// Returns the number of promised streams in the producer.
278  pub fn len(&self) -> usize {
279    self.sender.len()
280  }
281
282  /// Returns `true` if the producer is full.
283  pub fn is_full(&self) -> bool {
284    self.sender.is_full()
285  }
286
287  /// Returns `true` if the producer is closed.
288  pub fn is_closed(&self) -> bool {
289    self.sender.is_closed()
290  }
291
292  /// Closes the producer. Returns `true` if the producer was closed by this call.
293  pub fn close(&self) -> bool {
294    self.sender.close()
295  }
296}
297
298impl<A, S> StreamSubscriber<A, S> {
299  /// Receives a promised stream from the subscriber.
300  ///
301  /// If the subscriber is empty, this method waits until there is a message.
302  ///
303  /// If the subscriber is closed, this method receives a message or returns an error if there are
304  /// no more messages.
305  pub async fn recv(&self) -> Result<(A, S), RecvError> {
306    self.receiver.recv().await
307  }
308
309  /// Attempts to receive a message from the channel.
310  ///
311  /// If the channel is empty, or empty and closed, this method returns an error.
312  pub fn try_recv(&self) -> Result<(A, S), TryRecvError> {
313    self.receiver.try_recv()
314  }
315
316  /// Returns `true` if the subscriber is empty.
317  pub fn is_empty(&self) -> bool {
318    self.receiver.is_empty()
319  }
320
321  /// Returns the number of promised streams in the subscriber.
322  pub fn len(&self) -> usize {
323    self.receiver.len()
324  }
325
326  /// Returns `true` if the subscriber is full.
327  pub fn is_full(&self) -> bool {
328    self.receiver.is_full()
329  }
330
331  /// Returns `true` if the subscriber is closed.
332  pub fn is_closed(&self) -> bool {
333    self.receiver.is_closed()
334  }
335
336  /// Closes the subscriber. Returns `true` if the subscriber was closed by this call.
337  pub fn close(&self) -> bool {
338    self.receiver.close()
339  }
340}
341
342impl<A, S> Stream for StreamSubscriber<A, S> {
343  type Item = <Receiver<(A, S)> as Stream>::Item;
344
345  fn poll_next(
346    self: std::pin::Pin<&mut Self>,
347    cx: &mut std::task::Context<'_>,
348  ) -> std::task::Poll<Option<Self::Item>> {
349    <Receiver<_> as Stream>::poll_next(self.project().receiver, cx)
350  }
351}
352
353#[cfg(test)]
354mod tests {
355  use std::net::SocketAddr;
356
357  use bytes::Bytes;
358  use smol_str::SmolStr;
359
360  use super::*;
361
362  async fn access<R: RuntimeLite>() {
363    let messages = Message::<SmolStr, SocketAddr>::user_data(Bytes::new());
364    let timestamp = R::now();
365    let mut packet = Packet::<SocketAddr, _>::new(
366      "127.0.0.1:8080".parse().unwrap(),
367      timestamp,
368      messages.encode_to_bytes().unwrap(),
369    );
370    packet.set_from("127.0.0.1:8081".parse().unwrap());
371
372    let start = R::now();
373    packet.set_timestamp(start);
374    let messages = Message::<SmolStr, SocketAddr>::user_data(Bytes::from_static(b"a"))
375      .encode_to_bytes()
376      .unwrap();
377    packet.set_payload(messages);
378    assert_eq!(
379      packet.payload(),
380      &Message::<SmolStr, SocketAddr>::user_data(Bytes::from_static(b"a"))
381        .encode_to_bytes()
382        .unwrap(),
383    );
384    assert_eq!(
385      *packet.from(),
386      "127.0.0.1:8081".parse::<SocketAddr>().unwrap()
387    );
388    assert_eq!(*packet.timestamp(), start);
389  }
390
391  #[test]
392  fn tokio_access() {
393    tokio::runtime::Builder::new_current_thread()
394      .worker_threads(1)
395      .enable_all()
396      .build()
397      .unwrap()
398      .block_on(access::<agnostic_lite::tokio::TokioRuntime>());
399  }
400}