如何在期货0.3中以非阻塞方式对期货进行投票?

时间:2018-09-12 08:27:47

标签: rust

更新:由于来自Context签名的poll() got removed,此问题不再相关。


我正在尝试使用Future v0.3实现一个简单的futures crate:打开File

我的未来目前看起来像这样:

struct OpenFuture {
    options: OpenOptions,
    path:    PathBuf,
    output:  Option<io::Result<File>>,
}

要实现Future,我想到了这一点:

impl Future for OpenFuture {
    type Output = io::Result<File>;

    fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
        if let Some(file) = self.file.take() {
            Poll::Ready(file)
        } else {
            let waker = cx.waker().clone();
            cx.spawner().spawn_obj(
                Box::new(lazy(move |_| {
                    // self.file = Some(self.options.open(&self.path));
                    waker.wake();
                })).into(),
            );
            Poll::Pending
        }
    }
}

如果输出为Option::Some,则可以使用它,并且将来已经准备就绪,这很简单。但是,如果还没有准备好,我不想按照文档中所述阻塞线程:

  

poll的实现应努力迅速返回,并且绝不能阻塞。快速返回可防止不必要地阻塞线程或事件循环。如果提前得知对poll的调用可能要花一点时间,则应将工作卸载到线程池(或类似的线程)中,以确保poll可以快速返回。

所以我想分担工作。由于我有一个Context传递给poll方法,因此我可以访问SpawnWakerSpawn应该执行一个任务,该任务会打开文件。打开文件后,它会以waker.wake()进行通知。

由于生命周期错误,取消注释该行时,提供的代码不起作用:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
    |
    |                           Box::new(lazy(move |_| {
    |  _______________________________________^
    | |                             self.file = Some(self.options.open(&self.path));
    | |                             waker.wake();
    | |                         })).into(),
    | |_________________________^
    |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body...
    |
    |               fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
    |  _____________^
    | |                 if let Some(file) = self.file.take() {
    | |                     Poll::Ready(file)
    | |                 } else {
...   |
    | |                 }
    | |             }
    | |_____________^
    = note: ...so that the types are compatible:
            expected std::pin::PinMut<'_, _>
               found std::pin::PinMut<'_, _>
    = note: but, the lifetime must be valid for the static lifetime...
    = note: ...so that the expression is assignable:
            expected std::future::FutureObj<'static, _>
               found std::future::FutureObj<'_, _>

如何解决?

此外,Spawn::spawn_obj返回一个Result。如何处理此结果?建议只返回io::ErrorKind::Other吗?

0 个答案:

没有答案