struct DispatchTaskInner {
stream: Arc<RecordStream>,
flow_mode: FlowMode,
config: DispatchConfig,
}
pub struct DispatchTask {
inner: Arc<DispatchTaskInner>,
joiner: Mutex<Option<JoinHandle<()>>>,
token: CancellationToken,
subs: Arc<Subscriptions>,
}
impl DispatchTask {
pub fn start(&self) -> bool {
let mut guard = self.joiner.lock();
if guard.is_some() {
return false;
}
let inner = Arc::clone(&self.inner);
let subs = Arc::clone(&self.subs);
let token = self.token.clone();
debug!(stream=%inner.stream.name(), flow=%inner.flow_mode, "starting to dispatch");
let joiner = tokio::spawn(async move {
let mut dispatcher = make_dispatcher(subs.clone(), inner.config.clone());
loop {
let (records, more) = inner.stream.poll();
for record in &records {
dispatcher.dispatch(record);
}
if !more {
debug!("no more record: {}", inner.stream.name());
break;
}
if token.is_cancelled() {
info!("dispatch loop exited: {}", inner.stream.name());
break;
}
}
dispatcher.stop().await;
debug!(stream=%inner.stream.name(), flow=%inner.flow_mode, "dispatch terminated");
});
*guard = Some(joiner);
true
}
}
pub async fn stop(&self) {
let joiner = {
let mut guard = self.joiner.lock();
guard.take()
};
let Some(joiner) = joiner else {
return;
};
self.token.cancel();
debug!("dispatch stopping");
let _ = joiner.await;
debug!("dispatch stopped");
}
调试时:
- 都已经看到 dispatch terminated 日志了,但是看不到 dispatch stopped 这日志,不理解。
- 类似的结构有几层,发现 从其它让 tokio 跑几个任务,堵住的位置就不同,但是一样的操作,每次堵住的位置是一样的。
1
共 5 条评论, 1 页
评论区
写评论感觉找到了部分原因:
保存 JoinerHandle,主要是有管理需求:动态的部署和撤销数据流
👇
ThinkCodeStudio: 我不理解你为什么这么用, 这段代码好复杂, 我是启动任务后就不管task了, 也不会保存JoinHandle, 就相当于一个脱离控制的后台线程, 我控制这个task用的都是tokio的管道和事件, 比如关闭task我会发一个Notify信号, 数据交互都用的是管道
似乎不响应结果。主要是 我这里stop要 &mut,要清除保存它的Vec,放后面更顺手些。
👇
我是先await后关闭的, 不是先关闭后await, 我也不理解你为什么把await放的这么靠后
用的tokio的Mutex
--
👇
asuper: joiner: Mutex<Option<JoinHandle<()>>>,
你用的是std::sync::Mutex吧,这个不能在async里面用的
joiner: Mutex<Option<JoinHandle<()>>>,
你用的是std::sync::Mutex吧,这个不能在async里面用的
我不理解你为什么这么用, 这段代码好复杂, 我是启动任务后就不管task了, 也不会保存JoinHandle, 就相当于一个脱离控制的后台线程, 我控制这个task用的都是tokio的管道和事件, 比如关闭task我会发一个Notify信号, 数据交互都用的是管道
我是先await后关闭的, 不是先关闭后await, 我也不理解你为什么把await放的这么靠后