fix: 根据 code review 修复三个问题
根据 code review 反馈,修复以下问题: ## 1. High: 超时后未清理 ASR session - 在全局超时分支中添加 asr.cancel() 调用 - 避免 websocket/read tasks 继续运行造成资源泄漏 - 影响文件:coordinator.rs (dictation 和 QA 路径) ## 2. Medium: QA 路径缺少超时保护 - 为 QA 路径的 await_final_result() 添加相同的超时保护 - 保持 dictation 和 QA 路径的一致性 - 影响文件:coordinator.rs:2288-2298 ## 3. Medium: Watchdog 误报慢启动设备 - 将 last_callback_time 初始化从 Some(Instant::now()) 改为 None - 只有在第一次回调后才开始计时 - 避免慢启动设备被误判为"静默停止" - 影响文件:recorder.rs:333 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
e0d459bbd0
commit
2050524cbf
3 files changed
+21
-5
No files matched your search
@@ -1388,6 +1388,8 @@ async fn end_session(inner: &Arc<Inner>) -> Result<(), String> {
|
||||
"[coord] 全局超时 {} 秒 - 强制恢复",
|
||||
COORDINATOR_GLOBAL_TIMEOUT_SECS
|
||||
);
|
||||
// 清理 ASR session,避免资源泄漏
|
||||
asr.cancel();
|
||||
emit_capsule(
|
||||
inner,
|
||||
CapsuleState::Error,
|
||||
@@ -2286,13 +2288,26 @@ async fn end_qa_session(inner: &Arc<Inner>) -> Result<(), String> {
|
||||
if let Err(e) = asr.send_last_frame().await {
|
||||
log::error!("[coord] QA: send last frame failed: {e}");
|
||||
}
|
||||
let raw = match asr.await_final_result().await {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
// 添加全局超时保护:防止 await_final_result() 永远挂起
|
||||
let timeout_duration = std::time::Duration::from_secs(COORDINATOR_GLOBAL_TIMEOUT_SECS);
|
||||
let raw = match tokio::time::timeout(timeout_duration, asr.await_final_result()).await {
|
||||
Ok(Ok(r)) => r,
|
||||
Ok(Err(e)) => {
|
||||
log::error!("[coord] QA: await final failed: {e}");
|
||||
finish_qa_with_error(inner, format!("识别失败: {e}"));
|
||||
return Err(e.to_string());
|
||||
}
|
||||
Err(_) => {
|
||||
// 全局超时:最后的防线
|
||||
log::error!(
|
||||
"[coord] QA: 全局超时 {} 秒 - 强制恢复",
|
||||
COORDINATOR_GLOBAL_TIMEOUT_SECS
|
||||
);
|
||||
// 清理 ASR session,避免资源泄漏
|
||||
asr.cancel();
|
||||
finish_qa_with_error(inner, "识别超时".to_string());
|
||||
return Err("global timeout".to_string());
|
||||
}
|
||||
};
|
||||
|
||||
// cancel race:用户在 transcribe 中按 Esc / dismiss → 静默退出。
|
||||
|
||||
@@ -330,7 +330,8 @@ impl StreamState {
|
||||
callback_count: AtomicUsize::new(0),
|
||||
peak_input_rms_milli: AtomicUsize::new(0),
|
||||
peak_output_rms_milli: AtomicUsize::new(0),
|
||||
last_callback_time: Mutex::new(Some(std::time::Instant::now())),
|
||||
// 初始化为 None,只有在第一次回调后才开始计时,避免误报慢启动设备
|
||||
last_callback_time: Mutex::new(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next';
|
||||
import { isTauri, restartApp } from '../lib/ipc';
|
||||
import { Btn } from '../pages/_atoms';
|
||||
|
||||
const UPDATE_CHECK_TIMEOUT_MS = 15_000;
|
||||
const UPDATE_CHECK_TIMEOUT_MS = 8_000; // 缩短超时,让镜像站慢的情况能更快 fallback
|
||||
|
||||
export type UpdateStatus =
|
||||
| 'idle'
|
||||
|
||||
Reference in new issue
Block a user