代码之家  ›  专栏  ›  技术社区  ›  Tim Diekmann suresh madaparthi

如何在期货0.3中实现无阻塞的期货投票?

  •  1
  • Tim Diekmann suresh madaparthi  · 技术社区  · 6 年前

    更新 :此问题不再相关,因为 Context got removed poll() 签名。


    我正在尝试实现一个简单的 Future futures crate V0.3:打开A File 是的。

    我的未来现在是这样的:

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

    实施 未来 ,我想到了这个:

    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 要努力尽快归来,决不能阻拦快速返回可防止不必要地阻塞线程或事件循环如果提前知道 民意调查 可能需要一段时间,工作应该卸载到线程池(或类似的东西)中,以确保 民意调查 可以很快回来。

    所以我想把工作卸了因为我有一个 Context 传递给 投票 方法,我可以访问 Spawn 以及 Waker . 这个 产卵 应该接受一个任务,打开文件。文件打开后,它会通知 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 回复  |  直到 6 年前