rust - 如何在 Tokio 的 Sink 中使用 Pin?
问题描述
我想创建一个在实现 Tokio's 的结构上发送一些数据的方法Sink
,但是我在使用Pin
self. 本质上,我需要这样的东西:
fn send_data(&mut self, data: Item, cx: &mut Context) -> Poll<Result<(), Error>> {
futures_core::ready!(something.poll_ready(cx))?;
something.start_send(data)?;
futures_core::ready!(something.poll_close(cx))
}
问题是每次调用poll_ready()
,start_send()
和poll_close()
接受self: Pin<&mut Self>
,我不知道something
我的用例应该是什么。如果我尝试使用let something = Pin::new(self);
thensomething
在调用之后会被移动,poll_ready()
并且我不能将它用于后续调用(此时 self 也消失了)。我该如何解决这个问题?
use futures_core;
use std::pin::Pin;
use tokio::prelude::*; // 0.3.0-alpha.1
struct Test {}
impl Sink<i32> for Test {
type Error = ();
fn poll_ready(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn start_send(self: Pin<&mut Self>, item: i32) -> Result<(), Self::Error> {
Ok(())
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn poll_close(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
}
impl Test {
fn send_data(&mut self, data: i32, cx: &mut Context) -> Poll<Result<(), Error>> {
// what should "something" here be?
futures_core::ready!(something.poll_ready(cx))?;
something.start_send(data)?;
futures_core::ready!(something.poll_close(cx))
}
}
解决方案
我自己对 Rust 很陌生(本周才开始),但我今天早些时候通过执行以下操作解决了一个非常相似的问题:
- 创建一个固定版本
something
:let mut something_pinned = Box::pin(something);
.as_mut()
在每次调用、poll_ready
和start_send
之前调用poll_close
。
所以在你的send_data
,它应该看起来像:
futures_core::ready!(something_pinned.as_mut().poll_ready(cx))?;
something_pinned.as_mut().start_send(data)?;
futures_core::ready!(something_pinned.as_mut().poll_close(cx))
另外,我认为您通常应该存储您的哪些子轮询步骤已经完成的“记忆”,例如。这样当您的函数被重新调用时,它不会start_send
在已经看到它成功/准备就绪后调用额外的时间。(尽管在这种情况下冗余调用它可能不会导致任何实际问题)
推荐阅读
- javascript - 火库!如何通过 javascript 代码从数组中删除地图?
- python-3.x - RuntimeError:b'在初始化列表中没有参数'与pyproj geopandas
- visual-studio-2019 - 如何在 Visual Studio 2019 中的所有文件(甚至关闭的文件)上运行 ESLint
- haskell - 如何在haskell中获取数字的一部分
- ios - Swift - 如何按文本长度设置自定义视图
- javascript - 是否可以在 php 中包含 javascript 函数调用?
- c++ - 如何以编程方式清除 Windows 上的内部 Google Chrome DNS 缓存?
- python - 使用 Beautifulsoup 进行 Python 网页抓取:lowes 商店
- node.js - 我正在尝试制作一个不和谐的机器人,但我无法运行它
- python - 该函数在 Tkinter 中自行打开