Skip to content

Commit 110edce

Browse files
committed
fix(ai): 任务阶段诊断日志 + 前端30s卡住提示——定位真机排队中
1 parent 66367b3 commit 110edce

3 files changed

Lines changed: 53 additions & 3 deletions

File tree

‎app/src-tauri/src/commands_ai_refine.rs‎

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ pub fn ai_refine_apply(
244244
/// Pending(前端永久显示"任务排队中",无失败可重试)。
245245
/// catch_unwind 把 panic 归一为 Failed 状态,状态流转永不失联。
246246
fn run_refine_task(st: AppState, task_id: u64, session_id: i64, mock: bool) {
247+
// 诊断日志(2026-08-21 真机"排队中"排查):tauri dev 终端可见各阶段进度
248+
eprintln!("[refine-task] task={} start session={} mock={}", task_id, session_id, mock);
247249
let outcome = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
248250
run_refine_task_inner(&st, task_id, session_id, mock)
249251
}))
@@ -254,6 +256,12 @@ fn run_refine_task(st: AppState, task_id: u64, session_id: i64, mock: bool) {
254256
});
255257
match outcome {
256258
Ok(result) => {
259+
eprintln!(
260+
"[refine-task] task={} succeeded slices={} diff={}",
261+
task_id,
262+
result.slices,
263+
result.diff.len()
264+
);
257265
{
258266
let mut tasks = st.ai_tasks.lock().unwrap_or_else(|e| e.into_inner());
259267
if let Some(entry) = tasks.get_mut(&task_id) {
@@ -262,7 +270,10 @@ fn run_refine_task(st: AppState, task_id: u64, session_id: i64, mock: bool) {
262270
}
263271
set_task(&st, task_id, AiTaskState::Succeeded);
264272
}
265-
Err(reason) => set_task(&st, task_id, AiTaskState::Failed { reason }),
273+
Err(reason) => {
274+
eprintln!("[refine-task] task={} failed kind={}", task_id, reason.kind());
275+
set_task(&st, task_id, AiTaskState::Failed { reason });
276+
}
266277
}
267278
}
268279

@@ -280,9 +291,11 @@ fn run_refine_task_inner(
280291
};
281292
// ① 规则草稿 + 结构分析一次完成(审查修复 2026-08-21:build_rule_draft_
282293
// with_analysis 返回 analysis——章节/术语直接复用,消除二次 analyze 双跑)
294+
eprintln!("[refine-task] task={} 阶段①构建规则草稿(本地分析)", task_id);
283295
let (draft, analysis) =
284296
build_rule_draft_with_analysis(&st.db, &st.ui_junk, &env, &st.data_dir, session_id, None)
285297
.map_err(AiTaskFailure::Other)?;
298+
eprintln!("[refine-task] task={} 草稿完成 markdown={} 字符", task_id, draft.markdown.chars().count());
286299
// ② 精修上下文(档案/章节/术语——analysis 已含章节边界与术语表)
287300
let session = st
288301
.db
@@ -313,6 +326,7 @@ fn run_refine_task_inner(
313326
// ③ 切片(≤8000 字/片;进度按片上报)
314327
let slices = slice_note(&draft.markdown, SLICE_MAX_CHARS);
315328
let total = slices.len();
329+
eprintln!("[refine-task] task={} 切片 {} 片", task_id, total);
316330
set_task(st, task_id, AiTaskState::Running { finished_slices: 0, total_slices: total });
317331
let settings = st
318332
.ai_settings
@@ -335,6 +349,13 @@ fn run_refine_task_inner(
335349
} else {
336350
adapter.refine(&req).map_err(AiTaskFailure::from)?
337351
};
352+
eprintln!(
353+
"[refine-task] task={} 片 {}/{} 精修完成({} 节)",
354+
task_id,
355+
i + 1,
356+
total,
357+
resp.sections.len()
358+
);
338359
if !refined.is_empty() {
339360
refined.push_str("\n\n");
340361
}

‎app/src/components/AiRefineCard.tsx‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ export default function AiRefineCard({ sessionId, onApplied }: { sessionId: numb
6464
const [, setTaskId] = useState<number | null>(null);
6565
const taskIdRef = useRef<number | null>(null);
6666
const handleStateRef = useRef<(st: AiTaskState) => Promise<void>>(async () => {});
67+
// 卡住检测(2026-08-21 真机"排队中"排查):任务 30s 仍 Pending → 提示查看日志
68+
const lastChangeRef = useRef(0);
6769

6870
// 事件通道(ai:task-update)——与轮询双通道,事件优先即时;订阅一次,
6971
// 回调经 handleStateRef 取最新实现(无闭包过期)
@@ -126,9 +128,22 @@ export default function AiRefineCard({ sessionId, onApplied }: { sessionId: numb
126128

127129
const poll = (id: number) => {
128130
stopPolling();
131+
lastChangeRef.current = Date.now();
129132
polling.current = setInterval(async () => {
130133
const st = await invoke<AiTaskState>("ai_refine_status", { taskId: id }).catch(() => null);
131-
if (st) void handleState(st);
134+
if (st) {
135+
// 状态有进展(Running/Succeeded/Failed)→ 刷新时间戳;仅 Pending 计入卡住窗口
136+
if (st !== "Pending") lastChangeRef.current = Date.now();
137+
void handleStateRef.current(st);
138+
}
139+
// 卡住检测:长时间仍 Pending = 任务未启动或后台卡死(tauri 终端看 [refine-task] 日志)
140+
if (Date.now() - lastChangeRef.current > 30_000) {
141+
stopPolling();
142+
taskIdRef.current = null; // 隔离旧任务后续事件
143+
setTaskId(null);
144+
setPhase("idle");
145+
setMsg("任务 30 秒无进展(可能未启动或后台卡住)——请查看 tauri 终端 [refine-task] 日志后重试");
146+
}
132147
}, 1500);
133148
};
134149

‎app/src/components/EnrichPanel.tsx‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ export default function EnrichPanel({ noteId, onUpdated }: { noteId: number; onU
6767
// 事件/轮询回调用旧 taskId(null)查询结果而永久卡"排队中"
6868
const taskIdRef = useRef<number | null>(null);
6969
const handleStateRef = useRef<(st: AiTaskState) => Promise<void>>(async () => {});
70+
// 卡住检测(2026-08-21 真机"排队中"排查):任务 30s 仍 Pending → 提示查看日志
71+
const lastChangeRef = useRef(0);
7072

7173
useEffect(() => {
7274
void invoke<AiSettingsView>("ai_get_settings").then(setSettings).catch(() => undefined);
@@ -122,9 +124,21 @@ export default function EnrichPanel({ noteId, onUpdated }: { noteId: number; onU
122124

123125
const poll = (id: number) => {
124126
stopPolling();
127+
lastChangeRef.current = Date.now();
125128
polling.current = setInterval(async () => {
126129
const st = await invoke<AiTaskState>("ai_refine_status", { taskId: id }).catch(() => null);
127-
if (st) void handleState(st);
130+
if (st) {
131+
if (st !== "Pending") lastChangeRef.current = Date.now();
132+
void handleStateRef.current(st);
133+
}
134+
// 卡住检测:长时间仍 Pending = 任务未启动或后台卡死(tauri 终端看 [refine-task] 日志)
135+
if (Date.now() - lastChangeRef.current > 30_000) {
136+
stopPolling();
137+
taskIdRef.current = null;
138+
setTaskId(null);
139+
setPhase("idle");
140+
setMsg("任务 30 秒无进展(可能未启动或后台卡住)——请查看 tauri 终端 [refine-task] 日志后重试");
141+
}
128142
}, 1500);
129143
};
130144

0 commit comments

Comments
 (0)