1use core::ops::{Deref, DerefMut};
4use futures::{
5 StreamExt,
6 future::{self, AbortHandle, Abortable, Aborted},
7 stream::{FuturesUnordered, SelectNextSome},
8};
9use pin_project::pin_project;
10use std::{collections::BTreeMap, future::Future, pin::Pin, task::Poll};
11
12mod shared;
13mod try_join_all;
14pub use shared::{Shared, WeakShared};
15pub use try_join_all::try_join_all;
16
17type PooledFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
19
20pub struct Pool<'a, T> {
27 pool: FuturesUnordered<PooledFuture<'a, T>>,
28}
29
30impl<'a, T: Send> Default for Pool<'a, T> {
31 fn default() -> Self {
32 let pool = FuturesUnordered::new();
35 pool.push(Self::create_dummy_future());
36 Self { pool }
37 }
38}
39
40impl<'a, T: Send> Pool<'a, T> {
41 pub fn len(&self) -> usize {
43 self.pool.len().checked_sub(1).unwrap()
45 }
46
47 pub fn is_empty(&self) -> bool {
49 self.len() == 0
50 }
51
52 pub fn push(&mut self, future: impl Future<Output = T> + Send + 'a) {
56 self.pool.push(Box::pin(future));
57 }
58
59 pub fn next_completed(&mut self) -> SelectNextSome<'_, FuturesUnordered<PooledFuture<'a, T>>> {
63 self.pool.select_next_some()
64 }
65
66 pub fn cancel_all(&mut self) {
70 self.pool.clear();
71 self.pool.push(Self::create_dummy_future());
72 }
73
74 fn create_dummy_future() -> PooledFuture<'a, T> {
76 Box::pin(async { future::pending::<T>().await })
77 }
78}
79
80pub struct Aborter {
84 inner: AbortHandle,
85}
86
87impl Drop for Aborter {
88 fn drop(&mut self) {
89 self.inner.abort();
90 }
91}
92
93type AbortablePooledFuture<'a, T> = Pin<Box<dyn Future<Output = Result<T, Aborted>> + Send + 'a>>;
95
96pub struct AbortablePool<'a, T> {
104 pool: FuturesUnordered<AbortablePooledFuture<'a, T>>,
105}
106
107impl<'a, T: Send> Default for AbortablePool<'a, T> {
108 fn default() -> Self {
109 let pool = FuturesUnordered::new();
112 pool.push(Self::create_dummy_future());
113 Self { pool }
114 }
115}
116
117impl<'a, T: Send> AbortablePool<'a, T> {
118 pub fn len(&self) -> usize {
120 self.pool.len().checked_sub(1).unwrap()
122 }
123
124 pub fn is_empty(&self) -> bool {
126 self.len() == 0
127 }
128
129 pub fn push(&mut self, future: impl Future<Output = T> + Send + 'a) -> Aborter {
134 let (handle, registration) = AbortHandle::new_pair();
135 let abortable_future = Abortable::new(future, registration);
136 self.pool.push(Box::pin(abortable_future));
137 Aborter { inner: handle }
138 }
139
140 pub fn next_completed(
145 &mut self,
146 ) -> SelectNextSome<'_, FuturesUnordered<AbortablePooledFuture<'a, T>>> {
147 self.pool.select_next_some()
148 }
149
150 fn create_dummy_future() -> AbortablePooledFuture<'a, T> {
152 Box::pin(async { Ok(future::pending::<T>().await) })
153 }
154}
155
156#[pin_project]
162pub struct OptionFuture<F: Future>(#[pin] Option<F>);
163
164impl<F: Future> Default for OptionFuture<F> {
165 fn default() -> Self {
166 Self(None)
167 }
168}
169
170impl<F: Future> From<Option<F>> for OptionFuture<F> {
171 fn from(opt: Option<F>) -> Self {
172 Self(opt)
173 }
174}
175
176impl<F: Future> Deref for OptionFuture<F> {
177 type Target = Option<F>;
178
179 fn deref(&self) -> &Self::Target {
180 &self.0
181 }
182}
183
184impl<F: Future> DerefMut for OptionFuture<F> {
185 fn deref_mut(&mut self) -> &mut Self::Target {
186 &mut self.0
187 }
188}
189
190impl<F: Future> Future for OptionFuture<F> {
191 type Output = F::Output;
192
193 fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
194 let this = self.project();
195 this.0
196 .as_pin_mut()
197 .map_or_else(|| Poll::Pending, |fut| fut.poll(cx))
198 }
199}
200
201pub trait Threaded<T> {
211 type Rest;
213
214 fn split(self) -> (T, Self::Rest);
216}
217
218impl<T> Threaded<T> for T {
219 type Rest = ();
220
221 fn split(self) -> (T, ()) {
222 (self, ())
223 }
224}
225
226impl<T, A> Threaded<T> for (T, A) {
227 type Rest = A;
228
229 fn split(self) -> (T, A) {
230 self
231 }
232}
233
234impl<T, A, B> Threaded<T> for (T, A, B) {
235 type Rest = (A, B);
236
237 fn split(self) -> (T, (A, B)) {
238 let (value, a, b) = self;
239 (value, (a, b))
240 }
241}
242
243pub async fn rebind<T, Out, Fut, E>(
285 slot: &mut Option<T>,
286 op: impl FnOnce(T) -> Fut,
287) -> Result<Out::Rest, E>
288where
289 Out: Threaded<T>,
290 Fut: Future<Output = Result<Out, E>>,
291{
292 let value = slot.take().expect("cannot rebind an empty slot");
293 let (value, rest) = op(value).await?.split();
294 *slot = Some(value);
295 Ok(rest)
296}
297
298pub async fn rebind_entry<K, V, Out, Fut, E>(
342 map: &mut BTreeMap<K, V>,
343 key: &K,
344 op: impl FnOnce(V) -> Fut,
345) -> Result<Out::Rest, E>
346where
347 K: Ord,
348 Out: Threaded<V>,
349 Fut: Future<Output = Result<Out, E>>,
350{
351 let (key, value) = map
352 .remove_entry(key)
353 .expect("cannot rebind a missing entry");
354 let (value, rest) = op(value).await?.split();
355 map.insert(key, value);
356 Ok(rest)
357}
358
359#[cfg(test)]
360mod tests {
361 use super::*;
362 use crate::channel::oneshot;
363 use futures::{
364 executor::block_on,
365 future::{self, Either, select},
366 pin_mut,
367 };
368 use std::{
369 sync::{
370 Arc,
371 atomic::{AtomicBool, Ordering},
372 },
373 thread,
374 time::Duration,
375 };
376
377 fn delay(duration: Duration) -> impl Future<Output = ()> {
379 let (sender, receiver) = oneshot::channel();
380 thread::spawn(move || {
381 thread::sleep(duration);
382 sender.send(()).unwrap();
383 });
384 async move {
385 let _ = receiver.await;
386 }
387 }
388
389 #[test]
390 fn test_initialization() {
391 let pool = Pool::<i32>::default();
392 assert_eq!(pool.len(), 0);
393 assert!(pool.is_empty());
394 }
395
396 #[test]
397 fn test_dummy_future_doesnt_resolve() {
398 block_on(async {
399 let mut pool = Pool::<i32>::default();
400 let stream_future = pool.next_completed();
401 let timeout_future = async {
402 delay(Duration::from_millis(100)).await;
403 };
404 pin_mut!(stream_future);
405 pin_mut!(timeout_future);
406 let result = select(stream_future, timeout_future).await;
407 match result {
408 Either::Left((_, _)) => panic!("Stream resolved unexpectedly"),
409 Either::Right((_, _)) => {
410 }
412 }
413 });
414 }
415
416 #[test]
417 fn test_adding_futures() {
418 let mut pool = Pool::<i32>::default();
419 assert_eq!(pool.len(), 0);
420 assert!(pool.is_empty());
421
422 pool.push(async { 42 });
423 assert_eq!(pool.len(), 1);
424 assert!(!pool.is_empty(),);
425
426 pool.push(async { 43 });
427 assert_eq!(pool.len(), 2,);
428 }
429
430 #[test]
431 fn test_streaming_resolved_futures() {
432 block_on(async move {
433 let mut pool = Pool::<i32>::default();
434 pool.push(future::ready(42));
435 let result = pool.next_completed().await;
436 assert_eq!(result, 42,);
437 assert!(pool.is_empty(),);
438 });
439 }
440
441 #[test]
442 fn test_multiple_futures() {
443 block_on(async move {
444 let mut pool = Pool::<i32>::default();
445
446 let (finisher_1, finished_1) = oneshot::channel();
448 let (finisher_3, finished_3) = oneshot::channel();
449 pool.push(async move {
450 finished_1.await.unwrap();
451 finisher_3.send(()).unwrap();
452 1
453 });
454 pool.push(async move {
455 finisher_1.send(()).unwrap();
456 2
457 });
458 pool.push(async move {
459 finished_3.await.unwrap();
460 3
461 });
462
463 let first = pool.next_completed().await;
464 assert_eq!(first, 2, "First resolved should be 2");
465 let second = pool.next_completed().await;
466 assert_eq!(second, 1, "Second resolved should be 1");
467 let third = pool.next_completed().await;
468 assert_eq!(third, 3, "Third resolved should be 3");
469 assert!(pool.is_empty(),);
470 });
471 }
472
473 #[test]
474 fn test_cancel_all() {
475 block_on(async move {
476 let flag = Arc::new(AtomicBool::new(false));
477 let flag_clone = flag.clone();
478 let mut pool = Pool::<i32>::default();
479
480 let (finisher, finished) = oneshot::channel();
482 pool.push(async move {
483 finished.await.unwrap();
484 flag_clone.store(true, Ordering::SeqCst);
485 42
486 });
487 assert_eq!(pool.len(), 1);
488
489 pool.cancel_all();
491 assert!(pool.is_empty());
492 assert!(!flag.load(Ordering::SeqCst));
493
494 let _ = finisher.send(());
496
497 let stream_future = pool.next_completed();
499 let timeout_future = async {
500 delay(Duration::from_millis(100)).await;
501 };
502 pin_mut!(stream_future);
503 pin_mut!(timeout_future);
504 let result = select(stream_future, timeout_future).await;
505 match result {
506 Either::Left((_, _)) => panic!("Stream resolved after cancellation"),
507 Either::Right((_, _)) => {
508 }
510 }
511 assert!(!flag.load(Ordering::SeqCst));
512
513 pool.push(future::ready(42));
515 assert_eq!(pool.len(), 1);
516 let result = pool.next_completed().await;
517 assert_eq!(result, 42);
518 assert!(pool.is_empty());
519 });
520 }
521
522 #[test]
523 fn test_many_futures() {
524 block_on(async move {
525 let mut pool = Pool::<i32>::default();
526 let num_futures = 1000;
527 for i in 0..num_futures {
528 pool.push(future::ready(i));
529 }
530 assert_eq!(pool.len(), num_futures as usize);
531
532 let mut sum = 0;
533 for _ in 0..num_futures {
534 let value = pool.next_completed().await;
535 sum += value;
536 }
537 let expected_sum = (0..num_futures).sum::<i32>();
538 assert_eq!(
539 sum, expected_sum,
540 "Sum of resolved values should match expected"
541 );
542 assert!(
543 pool.is_empty(),
544 "Pool should be empty after all futures resolve"
545 );
546 });
547 }
548
549 #[test]
550 fn test_borrowing_futures() {
551 block_on(async {
552 let values = vec![1, 2, 3];
553
554 let mut pool = Pool::<&i32>::default();
556 for value in &values {
557 pool.push(async move { value });
558 }
559 assert_eq!(pool.len(), values.len());
560
561 let mut sum = 0;
562 for _ in 0..values.len() {
563 sum += *pool.next_completed().await;
564 }
565 assert_eq!(sum, 6);
566 assert!(pool.is_empty());
567 });
568 }
569
570 #[test]
571 fn test_abortable_pool_initialization() {
572 let pool = AbortablePool::<i32>::default();
573 assert_eq!(pool.len(), 0);
574 assert!(pool.is_empty());
575 }
576
577 #[test]
578 fn test_abortable_pool_adding_futures() {
579 let mut pool = AbortablePool::<i32>::default();
580 assert_eq!(pool.len(), 0);
581 assert!(pool.is_empty());
582
583 let _hook1 = pool.push(async { 42 });
584 assert_eq!(pool.len(), 1);
585 assert!(!pool.is_empty());
586
587 let _hook2 = pool.push(async { 43 });
588 assert_eq!(pool.len(), 2);
589 }
590
591 #[test]
592 fn test_abortable_pool_successful_completion() {
593 block_on(async move {
594 let mut pool = AbortablePool::<i32>::default();
595 let _hook = pool.push(future::ready(42));
596 let result = pool.next_completed().await;
597 assert_eq!(result, Ok(42));
598 assert!(pool.is_empty());
599 });
600 }
601
602 #[test]
603 fn test_abortable_pool_aborts_pre_polled_ready_future() {
604 block_on(async move {
605 let mut pool = AbortablePool::<i32>::default();
606 let hook = pool.push(future::ready(42));
607 drop(hook);
608 let result = pool.next_completed().await;
609 assert!(result.is_err());
610 });
611 }
612
613 #[test]
614 fn test_abortable_pool_drop_abort() {
615 block_on(async move {
616 let mut pool = AbortablePool::<i32>::default();
617
618 let (sender, receiver) = oneshot::channel();
619 let hook = pool.push(async move {
620 receiver.await.unwrap();
621 42
622 });
623
624 drop(hook);
625
626 let result = pool.next_completed().await;
627 assert!(result.is_err());
628 assert!(pool.is_empty());
629
630 let _ = sender.send(());
631 });
632 }
633
634 #[test]
635 fn test_abortable_pool_partial_abort() {
636 block_on(async move {
637 let mut pool = AbortablePool::<i32>::default();
638
639 let _hook1 = pool.push(future::ready(1));
640 let (sender, receiver) = oneshot::channel();
641 let hook2 = pool.push(async move {
642 receiver.await.unwrap();
643 2
644 });
645 let _hook3 = pool.push(future::ready(3));
646
647 assert_eq!(pool.len(), 3);
648
649 drop(hook2);
650
651 let mut results = Vec::new();
652 for _ in 0..3 {
653 let result = pool.next_completed().await;
654 results.push(result);
655 }
656
657 let successful: Vec<_> = results.iter().filter_map(|r| r.as_ref().ok()).collect();
658 let aborted: Vec<_> = results.iter().filter(|r| r.is_err()).collect();
659
660 assert_eq!(successful.len(), 2);
661 assert_eq!(aborted.len(), 1);
662 assert!(successful.contains(&&1));
663 assert!(successful.contains(&&3));
664 assert!(pool.is_empty());
665
666 let _ = sender.send(());
667 });
668 }
669
670 #[test]
671 fn test_abortable_pool_borrowing_futures() {
672 block_on(async {
673 let value = 42;
674 let mut pool = AbortablePool::<&i32>::default();
675
676 let (sender, receiver) = oneshot::channel::<()>();
678 let hook = pool.push(async {
679 receiver.await.unwrap();
680 &value
681 });
682 drop(hook);
683 assert!(pool.next_completed().await.is_err());
684
685 let _hook = pool.push(async { &value });
686 assert_eq!(pool.next_completed().await, Ok(&42));
687 assert!(pool.is_empty());
688
689 let _ = sender.send(());
690 });
691 }
692
693 #[test]
694 fn test_rebind_restores_value_and_yields_rest() {
695 block_on(async {
696 let mut slot = Some(1u32);
697 let rest: Result<(&str, bool), &str> = rebind(&mut slot, |value| {
698 future::ready(Ok((value + 1, "rest", true)))
699 })
700 .await;
701 assert_eq!(rest, Ok(("rest", true)));
702 assert_eq!(slot, Some(2));
703
704 let rest: Result<(), &str> =
705 rebind(&mut slot, |value| future::ready(Ok(value + 1))).await;
706 assert_eq!(rest, Ok(()));
707 assert_eq!(slot, Some(3));
708 });
709 }
710
711 #[test]
712 fn test_rebind_error_destroys_value() {
713 block_on(async {
714 let mut slot = Some(1u32);
715 let rest: Result<(), &str> =
716 rebind(&mut slot, |_| future::ready(Err::<u32, _>("failed"))).await;
717 assert_eq!(rest, Err("failed"));
718 assert_eq!(slot, None);
719 });
720 }
721
722 #[test]
723 #[should_panic(expected = "cannot rebind an empty slot")]
724 fn test_rebind_empty_slot_panics() {
725 block_on(async {
726 let mut slot: Option<u32> = None;
727 let _: Result<(), &str> = rebind(&mut slot, |v| future::ready(Ok(v))).await;
728 });
729 }
730
731 #[test]
732 fn test_rebind_entry_restores_value_and_yields_rest() {
733 block_on(async {
734 let mut map = BTreeMap::from([("a", 1u32), ("b", 10)]);
735 let rest: Result<bool, &str> =
736 rebind_entry(&mut map, &"a", |value| future::ready(Ok((value + 1, true)))).await;
737 assert_eq!(rest, Ok(true));
738 assert_eq!(map, BTreeMap::from([("a", 2), ("b", 10)]));
739 });
740 }
741
742 #[test]
743 fn test_rebind_entry_error_destroys_value() {
744 block_on(async {
745 let mut map = BTreeMap::from([("a", 1u32)]);
746 let rest: Result<(), &str> =
747 rebind_entry(&mut map, &"a", |_| future::ready(Err::<u32, _>("failed"))).await;
748 assert_eq!(rest, Err("failed"));
749 assert!(map.is_empty());
750 });
751 }
752
753 #[test]
754 #[should_panic(expected = "cannot rebind a missing entry")]
755 fn test_rebind_entry_missing_entry_panics() {
756 block_on(async {
757 let mut map: BTreeMap<&str, u32> = BTreeMap::new();
758 let _: Result<(), &str> = rebind_entry(&mut map, &"a", |v| future::ready(Ok(v))).await;
759 });
760 }
761
762 #[test]
763 fn test_option_future() {
764 block_on(async {
765 let option_future = OptionFuture::<oneshot::Receiver<()>>::from(None);
766 pin_mut!(option_future);
767
768 let waker = futures::task::noop_waker();
769 let mut cx = std::task::Context::from_waker(&waker);
770 assert!(option_future.poll(&mut cx).is_pending());
771
772 let (tx, rx) = oneshot::channel();
773 let option_future: OptionFuture<_> = Some(rx).into();
774 pin_mut!(option_future);
775
776 tx.send(1usize).unwrap();
777 assert_eq!(option_future.poll(&mut cx), Poll::Ready(Ok(1)));
778 });
779 }
780}