@@ -8,32 +8,40 @@ pub use equidistant::equidistant_intervals;
88pub use reporter:: TaskReporter ;
99use spdlog:: prelude:: * ;
1010pub use subscription:: TaskSubscription ;
11+ use tokio:: task:: JoinSet ;
1112
1213pub trait Task : Send {
1314 fn run ( & mut self ) -> Pin < Box < dyn Future < Output = ( ) > + Send + ' _ > > ;
1415}
1516
1617pub struct Runner {
17- join_handles : Vec < tokio :: task :: JoinHandle < ( ) > > ,
18+ join_set : JoinSet < ( ) > ,
1819}
1920
2021impl Runner {
21- pub async fn join_all ( self ) {
22- for join_handle in self . join_handles {
23- if let Err ( err) = join_handle. await {
24- error ! ( "failed to join task: {err}" ) ;
22+ pub async fn join_all ( mut self ) {
23+ while let Some ( join_handle) = self . join_set . join_next ( ) . await {
24+ if let Err ( err) = join_handle {
25+ if err. is_panic ( ) {
26+ error ! ( "task panicked: {err}" ) ;
27+ panic ! ( "task panicked: {err}" ) ;
28+ } else {
29+ error ! ( "failed to join task: {err}" ) ;
30+ }
2531 }
2632 }
2733 }
2834}
2935
3036pub async fn run_tasks ( tasks : impl IntoIterator < Item = Box < dyn Task > > ) -> anyhow:: Result < Runner > {
31- let join_handles = tasks
37+ let join_set = tasks
3238 . into_iter ( )
33- . map ( |mut task| tokio:: spawn ( async move { task. run ( ) . await } ) )
34- . collect :: < Vec < _ > > ( ) ;
39+ . fold ( JoinSet :: new ( ) , |mut join_set, mut task| {
40+ join_set. spawn ( async move { task. run ( ) . await } ) ;
41+ join_set
42+ } ) ;
3543
36- info ! ( "{} tasks are running" , join_handles . len( ) ) ;
44+ info ! ( "{} tasks are running" , join_set . len( ) ) ;
3745
38- Ok ( Runner { join_handles } )
46+ Ok ( Runner { join_set } )
3947}
0 commit comments