Почему порожденные фьючерсы не выполняются tokio_core :: реактор :: Core? - PullRequest
0 голосов
/ 27 октября 2018
extern crate tokio; // 0.1.8

use tokio::prelude::*;

fn create_a_future(x: u8) -> Box<Future<Item = (), Error = ()>> {
    Box::new(futures::future::ok(2).and_then(|a| {
        println!("{}", a);
        Ok(())
    }))
}

fn main() {
    let mut eloop = tokio_core::reactor::Core::new().unwrap();
    let handle = eloop.handle();

    for x in 0..10 {
        let f = create_a_future(x);
        handle.spawn(f);
    }
}

Я ожидаю, что это напечатает на стандартный вывод, но этого не произошло. Я неправильно использую spawn?

1 Ответ

0 голосов
/ 27 октября 2018

Как уже упоминалось в комментариях, вы настраиваете кучу вычислений, но никогда не запускаете их.Как итераторы, вы можете думать о фьючерсах как lazy .Компилятор обычно говорит вам об этом, когда вы создаете будущее, но никогда не используете его.Здесь вы порождаете фьючерсы, поэтому вы не получаете это предупреждение, но ничто никогда не приводит в действие реактор Токио.

Во многих случаях у вас есть конкретное будущее, которое вы хотите запустить, и вы будете управлятьреактор, пока это не завершится.В других случаях вы запускаете реактор «навсегда», бесконечно обрабатывая новые работы.

В этом случае вы можете использовать Core::turn:

fn main() {
    let mut eloop = tokio_core::reactor::Core::new().unwrap();
    let handle = eloop.handle();

    for x in 0..10 {
        let f = create_a_future(x);
        handle.spawn(f);
    }

    eloop.run(None);
}

eloop.turn(None);

-> Box<Future<Item = (), Error = ()>>

Вам не нужно (и, вероятно, не следует) делать это в современном Rust.Желательно вернуть анонимный тип:

fn create_a_future() -> impl Future<Item = (), Error = ()> {
    futures::future::ok(2).and_then(|a| {
        println!("{}", a);
        Ok(())
    })
}
 tokio_core::reactor::Core

Насколько я понимаю, этот уровень Tokio зарезервирован для более сложных установок.Многие люди могут просто использовать tokio::run и tokio::spawn:

fn main() {
    tokio::run(futures::lazy(|| {
        for _ in 0..10 {
            tokio::spawn(create_a_future());
        }
        Ok(())
    }))
}
...