Skip to content

Rust 异步

Introduction - Futures Explained in 200 Lines of Rust

Future

Future 需要 runtime 执行 poll 方法

pub trait Future {
    type Output;

    fn poll(
        self: Pin<&mut self>,
        cx: &mut Context<'_>,
    ) -> Poll<Self::Output>;
}

pub enums Poll<T> {
    Ready(T),
    Pending,
}

实现 Future 的实例,需要在 poll 方法实现自身不同状态时的操作

struct RequestHandler {
    server: &RpcServer,
    stream: TcpStream,
    id: i32,
    state: RHState,
    row_fut: Option<RowGet>,
}

impl Future for RequestHandler {
    type Output = ();
    fn poll(&mut self, cx: &mut Context) -> Poll<()> {
        match self.state {
            Unpolled => {
                self.row_fut = Some(get_row(&self.server, self.id));
                self.state = GettingRow;
            }
            GettingRow => {
                match self.row_fut.unwrap().poll(cx) {
                    Poll::Pending => return Poll::Pending,
                    Poll::Ready(row) => { self.row_fut = None;

                    }
                }
            }
        }
    }
}

Future in Box

Pinning - Asynchronous Programming in Rust

Box 内的 Future 需要实现 Unpin

impl<F> Future for Box<F>
where
    F: Unpin + Future + ?Sized,

使用 future::ready() 创建实现 UnpinFuture

Box::new(future::ready(Ok(true)))

或者创建包装 PinBox

Box::pin(async { Ok(true) })

使用 futures::future::BoxFuture

type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
// or
use futures::future::BoxFuture
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;

Tokio Runtime

tokio 实现 runtime 的形式

线程间传递数据

线程间调用 move 闭包