ntex_util/channel/
bstream.rs1use std::cell::{Cell, RefCell};
3use std::task::{Context, Poll};
4use std::{collections::VecDeque, fmt, future::poll_fn, pin::Pin, rc::Rc, rc::Weak};
5
6use ntex_bytes::Bytes;
7
8use crate::{Stream, task::LocalWaker};
9
10const MAX_BUFFER_SIZE: usize = 32_768;
12
13#[derive(Copy, Clone, Debug, PartialEq, Eq)]
15pub enum Status {
16 Eof,
18 Ready,
20 Dropped,
22}
23
24pub fn channel<E>() -> (Sender<E>, Receiver<E>) {
26 let inner = Rc::new(Inner::new(false));
27
28 (
29 Sender {
30 inner: Rc::downgrade(&inner),
31 },
32 Receiver { inner },
33 )
34}
35
36pub fn eof<E>() -> (Sender<E>, Receiver<E>) {
41 let inner = Rc::new(Inner::new(true));
42
43 (
44 Sender {
45 inner: Rc::downgrade(&inner),
46 },
47 Receiver { inner },
48 )
49}
50
51pub fn empty<E>(data: Option<Bytes>) -> Receiver<E> {
53 let rx = Receiver {
54 inner: Rc::new(Inner::new(true)),
55 };
56 if let Some(data) = data {
57 rx.put(data);
58 }
59 rx
60}
61
62#[derive(Debug)]
68pub struct Receiver<E> {
69 inner: Rc<Inner<E>>,
70}
71
72impl<E> Receiver<E> {
73 #[inline]
81 pub fn max_buffer_size(&self, size: usize) {
82 self.inner.set_max_buffer_size(size);
83 }
84
85 #[inline]
89 pub fn put(&self, data: Bytes) {
90 self.inner.unread_data(data);
91 }
92
93 #[inline]
94 pub fn is_eof(&self) -> bool {
98 self.inner.flags.get().contains(Flags::EOF)
99 }
100
101 #[inline]
102 pub async fn read(&self) -> Option<Result<Bytes, E>> {
104 poll_fn(|cx| self.poll_read(cx)).await
105 }
106
107 #[inline]
108 pub fn poll_read(&self, cx: &mut Context<'_>) -> Poll<Option<Result<Bytes, E>>> {
110 if let Some(data) = self.inner.get_data() {
111 Poll::Ready(Some(Ok(data)))
112 } else if let Some(err) = self.inner.err.take() {
113 self.inner.insert_flag(Flags::EOF);
114 Poll::Ready(Some(Err(err)))
115 } else if self.inner.flags.get().intersects(Flags::EOF | Flags::ERROR) {
116 Poll::Ready(None)
117 } else {
118 self.inner.recv_task.register(cx.waker());
119 Poll::Pending
120 }
121 }
122}
123
124impl<E> Stream for Receiver<E> {
125 type Item = Result<Bytes, E>;
126
127 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
128 self.poll_read(cx)
129 }
130}
131
132impl<E> Drop for Receiver<E> {
133 fn drop(&mut self) {
134 self.inner.send_task.wake();
135 }
136}
137
138#[derive(Debug)]
143pub struct Sender<E> {
144 inner: Weak<Inner<E>>,
145}
146
147impl<E> Clone for Sender<E> {
148 fn clone(&self) -> Self {
149 Self {
150 inner: self.inner.clone(),
151 }
152 }
153}
154
155impl<E> Drop for Sender<E> {
156 fn drop(&mut self) {
157 if self.inner.weak_count() == 1
158 && let Some(shared) = self.inner.upgrade()
159 {
160 shared.insert_flag(Flags::EOF | Flags::SENDER_GONE);
161 }
162 }
163}
164
165impl<E> Sender<E> {
166 pub fn is_closed(&self) -> bool {
168 self.inner.strong_count() == 0
169 }
170
171 pub fn set_error(&self, err: E) {
173 if let Some(shared) = self.inner.upgrade() {
174 shared.set_error(err);
175 }
176 }
177
178 pub fn feed_eof(&self) {
180 if let Some(shared) = self.inner.upgrade() {
181 shared.feed_eof();
182 }
183 }
184
185 pub fn feed_data(&self, data: Bytes) {
189 if let Some(shared) = self.inner.upgrade() {
190 shared.feed_data(data);
191 }
192 }
193
194 pub async fn ready(&self) -> Status {
196 poll_fn(|cx| self.poll_ready(cx)).await
197 }
198
199 pub fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Status> {
201 if let Some(shared) = self.inner.upgrade() {
202 let flags = shared.flags.get();
203 if flags.contains(Flags::NEED_READ) {
204 Poll::Ready(Status::Ready)
205 } else if flags.contains(Flags::SENDER_GONE | Flags::ERROR) {
206 Poll::Ready(Status::Dropped)
207 } else if flags.intersects(Flags::EOF) {
208 Poll::Ready(Status::Eof)
209 } else {
210 shared.send_task.register(cx.waker());
211 Poll::Pending
212 }
213 } else {
214 Poll::Ready(Status::Dropped)
216 }
217 }
218}
219
220bitflags::bitflags! {
221 #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
222 struct Flags: u8 {
223 const EOF = 0b0000_0001;
224 const ERROR = 0b0000_0010;
225 const NEED_READ = 0b0000_0100;
226 const SENDER_GONE = 0b0000_1000;
227 }
228}
229
230struct Inner<E> {
231 len: Cell<usize>,
232 flags: Cell<Flags>,
233 err: Cell<Option<E>>,
234 items: RefCell<VecDeque<Bytes>>,
235 max_buffer_size: Cell<usize>,
236 recv_task: LocalWaker,
237 send_task: LocalWaker,
238}
239
240impl<E> Inner<E> {
241 fn new(eof: bool) -> Self {
242 let flags = if eof { Flags::EOF } else { Flags::NEED_READ };
243 Inner {
244 flags: Cell::new(flags),
245 len: Cell::new(0),
246 err: Cell::new(None),
247 items: RefCell::new(VecDeque::new()),
248 recv_task: LocalWaker::new(),
249 send_task: LocalWaker::new(),
250 max_buffer_size: Cell::new(MAX_BUFFER_SIZE),
251 }
252 }
253
254 fn insert_flag(&self, f: Flags) {
255 let mut flags = self.flags.get();
256 flags.insert(f);
257 self.flags.set(flags);
258 }
259
260 fn remove_flag(&self, f: Flags) {
261 let mut flags = self.flags.get();
262 flags.remove(f);
263 self.flags.set(flags);
264 }
265
266 fn set_max_buffer_size(&self, size: usize) {
267 self.max_buffer_size.set(size);
268
269 let flags = self.flags.get();
270 if flags.intersects(Flags::EOF | Flags::ERROR | Flags::SENDER_GONE) {
271 return;
272 }
273
274 if self.len.get() < size {
275 if !flags.contains(Flags::NEED_READ) {
276 self.insert_flag(Flags::NEED_READ);
277 self.send_task.wake();
278 }
279 } else {
280 self.remove_flag(Flags::NEED_READ);
281 }
282 }
283
284 fn set_error(&self, err: E) {
285 self.err.set(Some(err));
286 self.insert_flag(Flags::ERROR);
287 self.recv_task.wake();
288 self.send_task.wake();
289 }
290
291 fn feed_eof(&self) {
292 self.insert_flag(Flags::EOF);
293 self.recv_task.wake();
294 self.send_task.wake();
295 }
296
297 fn feed_data(&self, data: Bytes) {
298 let len = self.len.get() + data.len();
299 self.len.set(len);
300 self.items.borrow_mut().push_back(data);
301 self.recv_task.wake();
302
303 if len >= self.max_buffer_size.get() {
304 self.remove_flag(Flags::NEED_READ);
305 }
306 }
307
308 fn get_data(&self) -> Option<Bytes> {
309 self.items.borrow_mut().pop_front().inspect(|data| {
310 let len = self.len.get() - data.len();
311
312 self.len.set(len);
315 if len < self.max_buffer_size.get() {
316 self.insert_flag(Flags::NEED_READ);
317 self.send_task.wake();
318 }
319 })
320 }
321
322 fn unread_data(&self, data: Bytes) {
323 if !data.is_empty() {
324 self.len.set(self.len.get() + data.len());
325 self.items.borrow_mut().push_front(data);
326 }
327 }
328}
329
330impl<E> fmt::Debug for Inner<E> {
331 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
332 f.debug_struct("Inner")
333 .field("len", &self.len)
334 .field("flags", &self.flags)
335 .field("items", &self.items.borrow())
336 .field("max_buffer_size", &self.max_buffer_size)
337 .field("recv_task", &self.recv_task)
338 .field("send_task", &self.send_task)
339 .finish()
340 }
341}
342
343#[cfg(test)]
344mod tests {
345 use super::*;
346 use crate::future::lazy;
347
348 #[ntex::test]
349 async fn test_eof() {
350 let (tx, rx) = eof::<()>();
351 rx.max_buffer_size(100);
352 assert!(rx.read().await.is_none());
353 assert_eq!(tx.ready().await, Status::Eof);
354 }
355
356 #[ntex::test]
357 async fn test_closed() {
358 let (tx, rx) = channel::<()>();
360 assert!(!tx.is_closed());
361 drop(rx);
362 assert!(tx.is_closed());
363
364 let (tx, rx) = channel::<()>();
366 drop(tx);
367 assert_eq!(rx.read().await, None);
368 }
369
370 #[ntex::test]
371 async fn test_unread_data() {
372 let (_, payload) = channel::<()>();
373
374 payload.put(Bytes::from("data"));
375 assert_eq!(payload.inner.len.get(), 4);
376 assert_eq!(
377 Bytes::from("data"),
378 poll_fn(|cx| payload.poll_read(cx)).await.unwrap().unwrap()
379 );
380 }
381
382 #[ntex::test]
383 async fn buffer_size_updates_sender_readiness() {
384 let (tx, rx) = channel::<()>();
385 rx.max_buffer_size(4);
386 tx.feed_data(Bytes::from_static(b"data"));
387
388 assert!(lazy(|cx| tx.poll_ready(cx)).await.is_pending());
389 assert!(rx.inner.send_task.is_set());
390
391 rx.max_buffer_size(5);
392 assert!(!rx.inner.send_task.is_set());
393 assert_eq!(
394 lazy(|cx| tx.poll_ready(cx)).await,
395 Poll::Ready(Status::Ready)
396 );
397
398 rx.max_buffer_size(4);
399 assert!(lazy(|cx| tx.poll_ready(cx)).await.is_pending());
400 }
401
402 #[ntex::test]
403 async fn test_sender_clone() {
404 let (sender, payload) = channel::<()>();
405 assert!(!payload.is_eof());
406 let sender2 = sender.clone();
407 assert!(!payload.is_eof());
408 drop(sender2);
409 assert!(!payload.is_eof());
410 drop(sender);
411 assert!(payload.is_eof());
412 }
413}