Как я могу эффективно извлечь первый элемент futures :: Stream блокирующим способом? - PullRequest
0 голосов
/ 03 марта 2019

У меня есть следующий метод:

pub fn load_names(&self, req: &super::MagicQueryType) -> ::grpcio::Result<::grpcio::ClientSStreamReceiver<String>> {

Моя цель - получить самый первый элемент grpcio::ClientSStreamReceiver;Меня не волнуют другие имена:

let name: String = load_names(query)?.wait().nth(0)?;

Кажется неэффективным вызывать wait() до nth(0), так как я считаю, wait() блокирует поток до тех пор, пока он не получит все элементы.

Как я могу написать более эффективное решение (например, nth(0).wait()), не вызывая ошибок сборки?Ошибки сборки Rust для futures::stream::Stream выглядят крайне смущающими для меня.

Rust Playground не поддерживает grpcio = "0.4.4", поэтому я не могу предоставить ссылку.

1 Ответ

0 голосов
/ 03 марта 2019

Чтобы извлечь первый элемент futures::Stream блокирующим образом, вы должны преобразовать Stream в итератор, вызвав Stream::wait, а затем вызвать Iterator::next.Чтение документации для Stream::wait показывает, что это в основном наиболее эффективная реализация:

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

use futures::{stream, Stream}; // 0.1.25
use std::iter;

fn example() -> impl Stream<Item = i32, Error = ()> {
    stream::iter_ok(iter::repeat(42))
}

fn main() {
    let v = example().wait().next();
    println!("{:?}", v);
}

Если вы используете Tokio, вы можете преобразовать Stream в Future и позвонить Runtime::block_on:

use std::iter;
use tokio::prelude::*; // 0.1.15

fn example() -> impl Stream<Item = i32, Error = ()> {
    stream::iter_ok(iter::repeat(42))
}

fn main() {
    let mut runtime = tokio::runtime::Runtime::new().expect("Unable to create a runtime");
    let r = runtime.block_on(example().into_future());
    if let Ok((v, _)) = r {
        println!("{:?}", v);
    }
}

См. Также:

...