with_err_spawn_group

Function with_err_spawn_group 

Source
pub async fn with_err_spawn_group<Closure, Fut, ResultType, ErrorType, ReturnType>(
    body: Closure,
) -> ReturnType
where Fut: Future<Output = ReturnType>, Closure: FnOnce(ErrSpawnGroup<ResultType, ErrorType>) -> Fut,
Expand description

Starts a scoped closure that takes a mutable ErrSpawnGroup instance as an argument which can execute any number of child tasks which its result values are of the type Result<ResultType, ErrorType> where ResultType can be of type and ErrorType which is any type that implements the standard Error type.

This closure ensures that before the function call ends, all spawned child tasks are implicitly waited for, or the programmer can explicitly wait by calling its wait_for_all() method of the ErrSpawnGroup struct

This function use a threadpoolof the same number of threads as the number of active processor count that is default amount of parallelism a program can use on the system for polling the spawned tasks

See ErrSpawnGroup for more.

§Parameters

  • body: an async closure that takes a mutable instance of ErrSpawnGroup as an argument

§Returns

Anything the body parameter returns

§Example

use std::error::Error;
use std::fmt::Display;
use spawn_groups::GetType;
use spawn_groups::with_err_spawn_group;
use futures_lite::StreamExt;
use spawn_groups::Priority;

#[derive(Debug)]
enum DivisibleByError {
    THREE,
    FIVE
}

impl Display for DivisibleByError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            DivisibleByError::THREE => f.write_str("Divisible by three"),
            DivisibleByError::FIVE => f.write_str("Divisible by five")
        }
    }
}

impl Error for DivisibleByError {}

let final_results = with_err_spawn_group(|mut group| async move {
    for i in 1..=10 {
        group.spawn_task(Priority::default(), async move {
         // simulate asynchronous processing that might fail and
         // return a value of ErrorType specified above
            if i % 3 == 0 {
               return Err(DivisibleByError::THREE)
            } else if i % 5 == 0 {
               return Err(DivisibleByError::FIVE)
            }
            Ok(i)
          });
       }
             
  // Explicitly wait for the all spawned child tasks to finish
    group.wait_for_all().await;

    let mut sum_result = 0;
    let mut divisible_by_five = 0;
    let mut divisible_by_three = 0;
    while let Some(group_result) = group.next().await {
       if let Ok(result) = group_result {
         sum_result += result;
       } else if let Err(err_result) = group_result {
           match err_result {
             DivisibleByError::THREE => divisible_by_three += 1,
             DivisibleByError::FIVE => divisible_by_five += 1
           }
       }
    }

    (sum_result, divisible_by_three, divisible_by_five)

}).await;

assert_eq!(final_results.0, 22);
assert_eq!(final_results.1, 3);
assert_eq!(final_results.2, 2);