Repository navigation
fix(logs): 退出流程关键节点补充日志,便于定位退出卡顿 #437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -374,15 +374,31 @@ pub fn run() { | |
| } | ||
| // 窗口关闭请求:检查是否最小化到托盘 | ||
| tauri::WindowEvent::CloseRequested { api, .. } => { | ||
| if tray::handle_close_requested(window.app_handle()) { | ||
| let minimize_to_tray = tray::handle_close_requested(window.app_handle()); | ||
| log::info!( | ||
| "[exit] Window '{}' close requested, minimize_to_tray={}", | ||
| window.label(), | ||
| minimize_to_tray | ||
| ); | ||
|
Comment on lines
+378
to
+382
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 中等 · 日志存储缓慢会延迟关闭 当配置的日志目录或其文件系统在关闭事件期间发生卡顿时,目录日志目标会在事件线程上同步写入。因此, 在关闭回调中使用非阻塞日志路径,或以其他方式确保日志写入卡顿不会阻塞事件处理。 另见 面向 AI agent 的提示在 `src-tauri/src/lib.rs` 第 378-382 行:
**日志存储缓慢会延迟关闭**
当配置的日志目录或其文件系统在关闭事件期间发生卡顿时,目录日志目标会在事件线程上同步写入。因此,`log::info!` 会在调用 `api.prevent_close()` 之前阻塞关闭处理,或使 `RunEvent::Exit` 清理延迟到日志写入完成;因此,日志文件系统卡顿会导致窗口或应用程序退出受阻。
在关闭回调中使用非阻塞日志路径,或以其他方式确保日志写入卡顿不会阻塞事件处理。
另见 `src-tauri/src/lib.rs:389-392`、`src-tauri/src/lib.rs:423`。Original comment in English🟡 Medium · Slow log storage delays shutdown When the configured log folder or its filesystem stalls during a shutdown event, the folder log target writes synchronously on the event thread, so Use a nonblocking log path for shutdown callbacks, or otherwise ensure a stalled log write cannot block event handling. Also at Prompt for AI agentsIn `src-tauri/src/lib.rs` at lines 378-382:
**Slow log storage delays shutdown**
When the configured log folder or its filesystem stalls during a shutdown event, the folder log target writes synchronously on the event thread, so `log::info!` blocks close handling before `api.prevent_close()` or delays `RunEvent::Exit` cleanup until the log write returns; a stalled log filesystem therefore stalls the window or application exit.
Use a nonblocking log path for shutdown callbacks, or otherwise ensure a stalled log write cannot block event handling.
Also at `src-tauri/src/lib.rs:389-392`, `src-tauri/src/lib.rs:423`. |
||
| if minimize_to_tray { | ||
| api.prevent_close(); | ||
| } | ||
| } | ||
| // 窗口销毁时清理所有 agent 子进程 | ||
| tauri::WindowEvent::Destroyed => { | ||
| log::info!( | ||
| "[exit] Window '{}' destroyed, cleaning up agent children", | ||
| window.label() | ||
| ); | ||
| let start = std::time::Instant::now(); | ||
| if let Some(state) = window.try_state::<Arc<MaaState>>() { | ||
| state.cleanup_all_agent_children(); | ||
| } | ||
| log::info!( | ||
| "[exit] Window '{}' cleanup finished in {}ms", | ||
| window.label(), | ||
| start.elapsed().as_millis() | ||
| ); | ||
| } | ||
| _ => {} | ||
| } | ||
|
|
@@ -396,13 +412,15 @@ pub fn run() { | |
| let final_exit_code = requested_exit_code.clone(); | ||
|
|
||
| let on_event = move |_app_handle: &tauri::AppHandle, event: tauri::RunEvent| { | ||
| #[cfg(windows)] | ||
| if let tauri::RunEvent::ExitRequested { code, .. } = &event { | ||
| log::info!("[exit] Exit requested, code={:?}", code); | ||
| #[cfg(windows)] | ||
| requested_exit_code.set(*code); | ||
| } | ||
|
|
||
| // 退出前收尾遥测(结束 Session 与悬挂 Transaction 并 flush) | ||
| if matches!(event, tauri::RunEvent::Exit) { | ||
| log::info!("[exit] Event loop exiting, running final cleanup"); | ||
| commands::focus::cancel_all(); | ||
| #[cfg(target_os = "macos")] | ||
| commands::notification::shutdown_macos_notifications(); | ||
|
|
@@ -418,7 +436,12 @@ pub fn run() { | |
| // tauri-runtime-wry 2.9.3 的 ControlFlow::Exit 丢失请求的退出码。 | ||
| // 先让事件循环完成退出回调和框架清理,再向操作系统报告该退出码。 | ||
| let runtime_exit_code = app.run_return(on_event); | ||
| std::process::exit(final_exit_code.get().unwrap_or(runtime_exit_code)); | ||
| let exit_code = final_exit_code.get().unwrap_or(runtime_exit_code); | ||
| log::info!( | ||
| "[exit] Event loop returned, exiting process with code {}", | ||
| exit_code | ||
| ); | ||
| std::process::exit(exit_code); | ||
| } | ||
| #[cfg(not(windows))] | ||
| app.run(on_event); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -95,6 +95,7 @@ export async function stopInstanceTasksAndExitApp(instanceId: string): Promise<b | |
| return true; | ||
| } | ||
|
|
||
| log.info(`[task-stop#${instanceId}] 任务已停止,请求退出应用`); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the Tauri exit path this call does not wait for the marker to reach disk: the logger method factory invokes the asynchronous Useful? React with 👍 / 👎.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 中等 · 退出标记未写入日志 当应用程序退出时,如果异步文件写入仍在等待中, 在调用 面向 AI agent 的提示在 `src/services/taskStopService.ts` 第 98 行:
**退出标记未写入日志**
当应用程序退出时,如果异步文件写入仍在等待中,`log.info` 会启动文件写入但不会等待其完成,而 `exit(0)` 可能会在写入完成前终止进程,因此退出前的标记不会出现在持久化日志中。
在调用 `exit(0)` 之前等待日志写入完成。Original comment in English🟡 Medium · Exit marker disappears from logs When the app exits while the asynchronous file write is pending, Await completion of the log write before calling Prompt for AI agentsIn `src/services/taskStopService.ts` at line 98:
**Exit marker disappears from logs**
When the app exits while the asynchronous file write is pending, `log.info` starts the file write without awaiting it, and `exit(0)` can terminate the process before it completes, so the pre-exit marker is absent from persisted logs.
Await completion of the log write before calling `exit(0)`. |
||
| const { exit } = await import('@tauri-apps/plugin-process'); | ||
| await exit(0); | ||
| return true; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 中等 · Agent 进程在关闭后仍然存活
当另一个线程持有
instances时发生 panic,cleanup_all_agent_children会在检查锁结果前记录已获取锁;随后if let Ok会因互斥锁已中毒而跳过清理。这样一来,即使 agent 子进程仍在运行,窗口处理程序也可能报告清理已完成。仅在成功获取锁后记录日志,并报告或处理因锁中毒导致的清理失败,而不是悄悄跳过。
面向 AI agent 的提示
Original comment in English
🟡 Medium · Agent processes survive shutdown
When another thread panicked while holding
instances,cleanup_all_agent_childrenlogs that it acquired the lock before checking the result, thenif let Okskips cleanup for the poisoned mutex; the window handler can report cleanup finished while agent children remain running.Log acquisition only after a successful lock, and report or handle the poisoned-lock cleanup failure instead of silently skipping it.
Prompt for AI agents