我将尝试构建一个对象,可以管理websocket的提要(feed),但要能够在多个提要(feed)之间切换。
有一个Feed特质:
有一个Feed特质:
trait Feed {
async fn start(&mut self);
async fn stop(&mut self);
}
有三个结构体实现了Feed
: A
,B
和C
。
当调用start
时,它会开始一个无限循环,监听来自websocket的消息并处理每个消息。
我想要实现一个FeedManager
,它维护单个活动的feed,但可以接收命令以切换使用哪个feed源。
enum FeedCommand {
Start(String),
Stop,
}
struct FeedManager {
active_feed_handle: tokio::task::JoinHandle,
controller: mpsc::Receiver<FeedCommand>,
}
impl FeedManager {
async fn start(&self) {
while let Some(command) = self.controller.recv().await {
match command {
FeedCommand::Start(feed_type) => {
// somehow tell the active feed to stop (need channel probably) or kill the task?
if feed_type == "A" {
// replace active feed task with a new tokio task for consuming feed A
} else if feed_type == "B" {
// replace active feed task with a new tokio task for consuming feed B
} else {
// replace active feed task with a new tokio task for consuming feed C
}
}
}
}
}
}
我很难理解如何正确管理所有的Tokio任务。 FeedManager
的核心循环是永久监听新进来的命令,但它需要能够生成另一个长期运行的任务而不会在此过程中发生阻塞(以便它可以继续监听命令)。
我的第一次尝试是:
if feed_type == "A" {
self.active_feed_handle = tokio::spawn(async {
A::new().start().await;
});
self.active_feed_handle.await
}
- 在句柄上使用
.await
会导致核心循环不再接受命令,是吗? - 我可以省略最后一个
.await
,任务仍然运行吗? - 我需要以某种方式清理当前活动任务吗?
async fn
。 - Shepmaster