File tree 6 files changed +63
-7
lines changed
6 files changed +63
-7
lines changed Original file line number Diff line number Diff line change @@ -17,6 +17,7 @@ pin_project! {
17
17
pub struct FromStream <S > {
18
18
#[ pin]
19
19
stream: S ,
20
+ limit: Option <usize >,
20
21
}
21
22
}
22
23
26
27
S : Send + Sync ,
27
28
{
28
29
FromStream {
30
+ limit : None ,
29
31
stream : stream. into_stream ( ) ,
30
32
}
31
33
}
40
42
let this = self . project ( ) ;
41
43
this. stream . poll_next ( cx)
42
44
}
45
+
46
+ fn set_limit ( mut self , limit : impl Into < Option < usize > > ) -> Self {
47
+ self . limit = limit. into ( ) ;
48
+ self
49
+ }
50
+
51
+ fn limit ( & self ) -> Option < usize > {
52
+ self . limit
53
+ }
43
54
}
Original file line number Diff line number Diff line change @@ -19,12 +19,14 @@ pin_project_lite::pin_project! {
19
19
exhausted: Arc <AtomicBool >,
20
20
// Count how many tasks are executing.
21
21
ref_count: Arc <AtomicU64 >,
22
+ // Max concurrency limit.
23
+ limit: Option <usize >,
22
24
}
23
25
}
24
26
25
27
impl ForEach {
26
28
/// Create a new instance of `ForEach`.
27
- pub fn new < S , F , Fut > ( mut input : S , mut f : F ) -> Self
29
+ pub fn new < S , F , Fut > ( mut stream : S , mut f : F ) -> Self
28
30
where
29
31
S : ParallelStream ,
30
32
F : FnMut ( S :: Item ) -> Fut + Send + Sync + Copy + ' static ,
@@ -39,10 +41,11 @@ impl ForEach {
39
41
receiver,
40
42
exhausted : exhausted. clone ( ) ,
41
43
ref_count : ref_count. clone ( ) ,
44
+ limit : stream. limit ( ) ,
42
45
} ;
43
46
44
47
task:: spawn ( async move {
45
- while let Some ( item) = input . next ( ) . await {
48
+ while let Some ( item) = stream . next ( ) . await {
46
49
let sender = sender. clone ( ) ;
47
50
let exhausted = exhausted. clone ( ) ;
48
51
let ref_count = ref_count. clone ( ) ;
Original file line number Diff line number Diff line change @@ -14,6 +14,7 @@ pin_project_lite::pin_project! {
14
14
pub struct Map <T > {
15
15
#[ pin]
16
16
receiver: Receiver <T >,
17
+ limit: Option <usize >,
17
18
}
18
19
}
19
20
@@ -26,6 +27,7 @@ impl<T: Send + 'static> Map<T> {
26
27
Fut : Future < Output = T > + Send ,
27
28
{
28
29
let ( sender, receiver) = sync:: channel ( 1 ) ;
30
+ let limit = stream. limit ( ) ;
29
31
task:: spawn ( async move {
30
32
while let Some ( item) = stream. next ( ) . await {
31
33
let sender = sender. clone ( ) ;
@@ -35,7 +37,7 @@ impl<T: Send + 'static> Map<T> {
35
37
} ) ;
36
38
}
37
39
} ) ;
38
- Map { receiver }
40
+ Map { receiver, limit }
39
41
}
40
42
}
41
43
@@ -46,6 +48,15 @@ impl<T: Send + 'static> ParallelStream for Map<T> {
46
48
let this = self . project ( ) ;
47
49
this. receiver . poll_next ( cx)
48
50
}
51
+
52
+ fn set_limit ( mut self , limit : impl Into < Option < usize > > ) -> Self {
53
+ self . limit = limit. into ( ) ;
54
+ self
55
+ }
56
+
57
+ fn limit ( & self ) -> Option < usize > {
58
+ self . limit
59
+ }
49
60
}
50
61
51
62
#[ async_std:: test]
Original file line number Diff line number Diff line change @@ -21,6 +21,12 @@ pub trait ParallelStream: Sized + Send + Sync + Unpin + 'static {
21
21
/// Attempts to receive the next item from the stream.
22
22
fn poll_next ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > ;
23
23
24
+ /// Set a max concurrency limit
25
+ fn set_limit ( self , limit : impl Into < Option < usize > > ) -> Self ;
26
+
27
+ /// Get the max concurrency limit
28
+ fn limit ( & self ) -> Option < usize > ;
29
+
24
30
/// Applies `f` to each item of this stream in parallel, producing a new
25
31
/// stream with the results.
26
32
fn map < F , T , Fut > ( self , f : F ) -> Map < T >
Original file line number Diff line number Diff line change @@ -17,14 +17,19 @@ pin_project! {
17
17
#[ derive( Clone , Debug ) ]
18
18
pub struct Take <S > {
19
19
#[ pin]
20
- pub ( crate ) stream: S ,
21
- pub ( crate ) remaining: usize ,
20
+ stream: S ,
21
+ remaining: usize ,
22
+ limit: Option <usize >,
22
23
}
23
24
}
24
25
25
- impl < S > Take < S > {
26
+ impl < S : ParallelStream > Take < S > {
26
27
pub ( super ) fn new ( stream : S , remaining : usize ) -> Self {
27
- Self { stream, remaining }
28
+ Self {
29
+ limit : stream. limit ( ) ,
30
+ remaining,
31
+ stream,
32
+ }
28
33
}
29
34
}
30
35
@@ -44,4 +49,13 @@ impl<S: ParallelStream> ParallelStream for Take<S> {
44
49
Poll :: Ready ( next)
45
50
}
46
51
}
52
+
53
+ fn set_limit ( mut self , limit : impl Into < Option < usize > > ) -> Self {
54
+ self . limit = limit. into ( ) ;
55
+ self
56
+ }
57
+
58
+ fn limit ( & self ) -> Option < usize > {
59
+ self . limit
60
+ }
47
61
}
Original file line number Diff line number Diff line change @@ -17,6 +17,7 @@ pin_project_lite::pin_project! {
17
17
pub struct IntoParStream <T > {
18
18
#[ pin]
19
19
stream: FromStream <FromIter <vec:: IntoIter <T >>>,
20
+ limit: Option <usize >,
20
21
}
21
22
}
22
23
@@ -26,6 +27,15 @@ impl<T: Send + Sync + 'static> ParallelStream for IntoParStream<T> {
26
27
let this = self . project ( ) ;
27
28
this. stream . poll_next ( cx)
28
29
}
30
+
31
+ fn set_limit ( mut self , limit : impl Into < Option < usize > > ) -> Self {
32
+ self . limit = limit. into ( ) ;
33
+ self
34
+ }
35
+
36
+ fn limit ( & self ) -> Option < usize > {
37
+ self . limit
38
+ }
29
39
}
30
40
31
41
impl < T : Send + Sync + ' static > IntoParallelStream for Vec < T > {
@@ -36,6 +46,7 @@ impl<T: Send + Sync + 'static> IntoParallelStream for Vec<T> {
36
46
fn into_par_stream ( self ) -> Self :: IntoParStream {
37
47
IntoParStream {
38
48
stream : from_stream ( from_iter ( self ) ) ,
49
+ limit : None ,
39
50
}
40
51
}
41
52
}
You can’t perform that action at this time.
0 commit comments