Spec-Zone.ru › Tokio

Макрос try_join

macro_rules! try_join {
    ($(biased;)? $($future:expr),*) => { ... };
}
Доступно только при включённой функции crate macros.

Ожидает завершения нескольких одновременно выполняющихся ветвей, возвращая результат, когда все ветви завершаются с Ok(_), или при первом Err(_).

Макрос try_join! необходимо использовать внутри асинхронных функций, замыканий и блоков.

Как и join!, макрос try_join! принимает список асинхронных выражений и вычисляет их одновременно в рамках одной задачи. Каждое асинхронное выражение вычисляется в future, а future из каждого выражения мультиплексируются в текущей задаче. Макрос try_join! возвращает результат, когда все ветви завершаются с Ok или когда первая ветвь завершается с Err.

Примечания

Переданные future хранятся непосредственно и не требуют выделения Vec.

Особенности работы

Запуская все асинхронные выражения в текущей задаче, эти выражения могут выполняться одновременно, но не параллельно. Это означает, что все выражения выполняются в одном потоке, и если одна ветвь блокирует поток, все остальные выражения не смогут продолжить работу. Если требуется параллельное выполнение, запустите каждое асинхронное выражение с помощью tokio::spawn и передайте макросу try_join! дескриптор объединения.

Справедливость

По умолчанию future, создаваемый макросом try_join!, при каждом пробуждении меняет порядок опроса содержащихся в нём future, выбирая другой future для первого опроса.

Это поведение можно переопределить, добавив biased; в начало вызова макроса. Подробности см. в примерах. В этом случае try_join будет опрашивать future в порядке их появления сверху вниз.

Это может быть полезно, если future могут взаимодействовать таким образом, что важен известный порядок опроса.

Однако у этого режима есть важная оговорка. Вы сами отвечаете за обеспечение справедливого порядка опроса future. Например, если вы объединяете поток и future завершения работы, а в потоке содержится огромное количество сообщений, обработка которых при каждом опросе занимает много времени, следует поместить future завершения работы раньше в списке try_join!, чтобы он всегда опрашивался и не задерживался из-за того, что future потока долго не возвращает Poll::Pending.

Примеры

Простой пример try_join с двумя ветвями.

async fn do_stuff_async() -> Result<(), &'static str> {
    // async work
}

async fn more_async_work() -> Result<(), &'static str> {
    // more here
}

let res = tokio::try_join!(
    do_stuff_async(),
    more_async_work());

match res {
    Ok((first, second)) => {
        // do something with the values
    }
    Err(err) => {
        println!("processing failed; error = {}", err);
    }
}

Использование try_join! с запущенными задачами.

use tokio::task::JoinHandle;

async fn do_stuff_async() -> Result<(), &'static str> {
    // async work
}

async fn more_async_work() -> Result<(), &'static str> {
    // more here
}

async fn flatten<T>(handle: JoinHandle<Result<T, &'static str>>) -> Result<T, &'static str> {
    match handle.await {
        Ok(Ok(result)) => Ok(result),
        Ok(Err(err)) => Err(err),
        Err(err) => Err("handling failed"),
    }
}

let handle1 = tokio::spawn(do_stuff_async());
let handle2 = tokio::spawn(more_async_work());
match tokio::try_join!(flatten(handle1), flatten(handle2)) {
    Ok(val) => {
        // do something with the values
    }
    Err(err) => {
        println!("Failed with {}.", err);
    }
}

Использование режима biased; для управления порядком опроса.

async fn do_stuff_async() -> Result<(), &'static str> {
    // async work
}

async fn more_async_work() -> Result<(), &'static str> {
    // more here
}

let res = tokio::try_join!(
    biased;
    do_stuff_async(),
    more_async_work()
);

match res {
    Ok((first, second)) => {
        // do something with the values
    }
    Err(err) => {
        println!("processing failed; error = {}", err);
    }
}

MIT License
Copyright © Tokio Contributors
https://docs.rs/tokio/1.53.1/tokio/macro.try_join.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API