Получение нескольких URL-адресов одновременно с Hyper

Я пытаюсь адаптировать пример базового клиента Hyper для одновременного получения нескольких URL.

Вот код, который у меня сейчас есть:

extern crate futures;
extern crate hyper;
extern crate tokio_core;

use std::io::{self, Write};
use std::iter;
use futures::{Future, Stream};
use hyper::Client;
use tokio_core::reactor::Core;

fn get_url() {
    let mut core = Core::new().unwrap();
    let client = Client::new(&core.handle());
    let uris: Vec<_> = iter::repeat("http://httpbin.org/ip".parse().unwrap()).take(50).collect();
    for uri in uris {
        let work = client.get(uri).and_then(|res| {
            println!("Response: {}", res.status());

            res.body().for_each(|chunk| {
                io::stdout()
                    .write_all(&chunk)
                    .map_err(From::from)
            })
        });
        core.run(work).unwrap();
    }
}

fn main() {
    get_url();
}

Похоже, что он не работает одновременно (это занимает много времени), я неправильно передаю работу ядру?

1 ответ

Решение

я неправильно даю работу ядру?

Да, вы даете один запрос ядру, а затем требует его выполнения перед началом следующего запроса. Вы взяли асинхронный код и заставили его быть последовательным.

Вам нужно дать реактору единое будущее, которое будет выполнять разные виды параллельной работы:

extern crate futures;
extern crate hyper;
extern crate tokio_core;

use std::io::{self, Write};
use std::iter;
use futures::{stream, Future, Stream};
use hyper::Client;
use tokio_core::reactor::Core;

fn get_url() {
    let mut core = Core::new().unwrap();
    let client = Client::new(&core.handle());

    let uri = "http://httpbin.org/ip".parse().unwrap();
    let uris = iter::repeat(uri).take(50);

    let work = stream::iter_ok(uris)
        .map(|uri| client.get(uri))
        .buffer_unordered(1)
        .and_then(|res| {
            println!("Response: {}", res.status());
            res.body().concat2().from_err()
        })
        .for_each(|body| {
            io::stdout().write_all(&body).map_err(From::from)
        });

    core.run(work).unwrap();
}

fn main() {
    get_url();
}

С buffer_unordered установить в 1:

real    0m1.486s
user    0m0.161s
sys     0m0.168s

И установите на 10:

real    0m0.871s
user    0m0.159s
sys     0m0.170s
Другие вопросы по тегам