![](/img/trans.png)
[英]How do I pass these references to a function that spawns a tokio task?
[英]How do I schedule a repeating task in Tokio?
我正在使用Tokio用异步等效项替换用Rust编写的同步套接字代码。 Tokio使用Future进行异步活动,因此任务被链接在一起并排队到要由线程池执行的执行程序上。
我想做的基本伪代码是这样的:
let tokio::net::listener = TcpListener::bind(&sock_addr).unwrap();
let server_task = listener.incoming().for_each(move |socket| {
let in_buf = vec![0u8; 8192];
// TODO this should happen continuously until an error happens
let read_task = tokio::io::read(socket, in_buf).and_then(move |(socket, in_buf, bytes_read)| {
/* ... Logic I want to happen repeatedly as bytes are read ... */
Ok(())
};
tokio::spawn(read_task);
Ok(())
}).map_err(|err| {
error!("Accept error = {:?}", err);
});
tokio::run(server_task);
这个伪代码只会执行一次我的任务。 如何连续运行? 我希望它执行,然后一次又一次执行,等等。我只希望它在出现紧急情况或有错误结果代码时停止执行。 最简单的方法是什么?
使用loop_fn
应该可以:
let read_task =
futures::future::loop_fn((socket, in_buf, 0), |(socket, in_buf, bytes_read)| {
if bytes_read > 0 { /* handle bytes */ }
tokio::io::read(socket, in_buf).map(Loop::Continue)
});
无需使用类型系统即可完成此任务的一种干净方法是使用tokio-codec
板条箱; 如果要作为字节流与阅读器进行交互,而不是定义编解码器,则可以使用tokio_codec::BytesCodec
。
use tokio::codec::Decoder;
use futures::Stream;
...
let tokio::net::listener = TcpListener::bind(&sock_addr).unwrap();
let server_task = listener.incoming().for_each(move |socket| {
let (_writer, reader) = tokio_codec::BytesCodec::new().framed(socket).split();
let read_task = reader.for_each(|bytes| {
/* ... Logic I want to happen repeatedly as bytes are read ... */
});
tokio::spawn(read_task);
Ok(())
}).map_err(|err| {
error!("Accept error = {:?}", err);
});
tokio::run(server_task);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.