-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement try_join_next #6280
implement try_join_next #6280
Changes from all commits
f20d21b
12ca484
f575b0c
a59de4a
e3ab761
350a787
bc28eb2
92a835b
fc679bb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The test is nice. Especially the fact that you cover the case with coop budgeting. You don't have any tests that handle the case where it returns None even though there are tasks, because all the tasks are still running. Could you do that? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure! |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -227,3 +227,80 @@ async fn join_set_coop() { | |
assert!(coop_count >= 1); | ||
assert_eq!(count, TASK_NUM); | ||
} | ||
|
||
#[tokio::test(flavor = "current_thread")] | ||
async fn try_join_next() { | ||
const TASK_NUM: u32 = 1000; | ||
|
||
let (send, recv) = tokio::sync::watch::channel(()); | ||
|
||
let mut set = JoinSet::new(); | ||
|
||
for _ in 0..TASK_NUM { | ||
let mut recv = recv.clone(); | ||
set.spawn(async move { recv.changed().await.unwrap() }); | ||
} | ||
drop(recv); | ||
|
||
assert!(set.try_join_next().is_none()); | ||
|
||
send.send_replace(()); | ||
send.closed().await; | ||
Comment on lines
+247
to
+248
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not actually guaranteed that the tasks are considered finished by the If you make this into a current-thread runtime, then this race goes away. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah you're right. Fixed it. |
||
|
||
let mut count = 0; | ||
loop { | ||
match set.try_join_next() { | ||
Some(Ok(())) => { | ||
count += 1; | ||
} | ||
Some(Err(err)) => panic!("failed: {}", err), | ||
None => { | ||
break; | ||
} | ||
} | ||
} | ||
|
||
assert_eq!(count, TASK_NUM); | ||
} | ||
|
||
#[cfg(tokio_unstable)] | ||
#[tokio::test(flavor = "current_thread")] | ||
async fn try_join_next_with_id() { | ||
const TASK_NUM: u32 = 1000; | ||
|
||
let (send, recv) = tokio::sync::watch::channel(()); | ||
|
||
let mut set = JoinSet::new(); | ||
let mut spawned = std::collections::HashSet::with_capacity(TASK_NUM as usize); | ||
|
||
for _ in 0..TASK_NUM { | ||
let mut recv = recv.clone(); | ||
let handle = set.spawn(async move { recv.changed().await.unwrap() }); | ||
|
||
spawned.insert(handle.id()); | ||
} | ||
drop(recv); | ||
|
||
assert!(set.try_join_next_with_id().is_none()); | ||
|
||
send.send_replace(()); | ||
send.closed().await; | ||
|
||
let mut count = 0; | ||
let mut joined = std::collections::HashSet::with_capacity(TASK_NUM as usize); | ||
loop { | ||
match set.try_join_next_with_id() { | ||
Some(Ok((id, ()))) => { | ||
count += 1; | ||
joined.insert(id); | ||
} | ||
Some(Err(err)) => panic!("failed: {}", err), | ||
None => { | ||
break; | ||
} | ||
} | ||
} | ||
|
||
assert_eq!(count, TASK_NUM); | ||
assert_eq!(joined, spawned); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment about why you go around the loop when it returns
Pending
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Loop over all notified `JoinHandle`s to find one that's ready, or until none are left.
I've added this comment at the top of the function to explain why the loop exists. Is it too concise?