Repository navigation
Conversation
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5d537c7d55
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| return true; | ||
| } | ||
|
|
||
| log.info(`[task-stop#${instanceId}] 任务已停止,请求退出应用`); |
There was a problem hiding this comment.
In the Tauri exit path this call does not wait for the marker to reach disk: the logger method factory invokes the asynchronous writeLogToFile at src/utils/logger.ts:152-160 without returning its promise, and this function immediately proceeds to exit(0). On a fast exit or concurrent backend command dispatch, the WebView/process can be torn down before the plugin-fs append completes, so the marker intended to prove execution reached the exit request can be absent; use an awaited write/flush or a synchronous backend log command before requesting exit.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
嗨——我发现了 3 个问题
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="src-tauri/src/commands/types.rs" line_range="806-809" />
<code_context>
- if let Ok(mut instances) = self.instances.lock() {
+ let lock_start = std::time::Instant::now();
+ let instances = self.instances.lock();
+ log::info!(
+ "[exit] Acquired instances lock for agent cleanup in {}ms",
+ lock_start.elapsed().as_millis()
+ );
+ if let Ok(mut instances) = instances {
for (id, instance) in instances.iter_mut() {
</code_context>
<issue_to_address>
**Agent processes survive shutdown**
When another thread panicked while holding `instances`, `cleanup_all_agent_children` logs that it acquired the lock before checking the result, then `if let Ok` skips 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.
</issue_to_address>
### Comment 2
<location path="src-tauri/src/lib.rs" line_range="378-382" />
<code_context>
- if let Ok(mut instances) = self.instances.lock() {
+ let lock_start = std::time::Instant::now();
+ let instances = self.instances.lock();
+ log::info!(
+ "[exit] Acquired instances lock for agent cleanup in {}ms",
+ lock_start.elapsed().as_millis()
+ );
+ if let Ok(mut instances) = instances {
for (id, instance) in instances.iter_mut() {
</code_context>
<issue_to_address>
**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`.
</issue_to_address>
### Comment 3
<location path="src/services/taskStopService.ts" line_range="98" />
<code_context>
return true;
}
+ log.info(`[task-stop#${instanceId}] 任务已停止,请求退出应用`);
const { exit } = await import('@tauri-apps/plugin-process');
await exit(0);
</code_context>
<issue_to_address>
**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)`.
</issue_to_address>Original comment in English
Hey - I've found 3 issues
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="src-tauri/src/commands/types.rs" line_range="806-809" />
<code_context>
- if let Ok(mut instances) = self.instances.lock() {
+ let lock_start = std::time::Instant::now();
+ let instances = self.instances.lock();
+ log::info!(
+ "[exit] Acquired instances lock for agent cleanup in {}ms",
+ lock_start.elapsed().as_millis()
+ );
+ if let Ok(mut instances) = instances {
for (id, instance) in instances.iter_mut() {
</code_context>
<issue_to_address>
**Agent processes survive shutdown**
When another thread panicked while holding `instances`, `cleanup_all_agent_children` logs that it acquired the lock before checking the result, then `if let Ok` skips 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.
</issue_to_address>
### Comment 2
<location path="src-tauri/src/lib.rs" line_range="378-382" />
<code_context>
- if let Ok(mut instances) = self.instances.lock() {
+ let lock_start = std::time::Instant::now();
+ let instances = self.instances.lock();
+ log::info!(
+ "[exit] Acquired instances lock for agent cleanup in {}ms",
+ lock_start.elapsed().as_millis()
+ );
+ if let Ok(mut instances) = instances {
for (id, instance) in instances.iter_mut() {
</code_context>
<issue_to_address>
**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`.
</issue_to_address>
### Comment 3
<location path="src/services/taskStopService.ts" line_range="98" />
<code_context>
return true;
}
+ log.info(`[task-stop#${instanceId}] 任务已停止,请求退出应用`);
const { exit } = await import('@tauri-apps/plugin-process');
await exit(0);
</code_context>
<issue_to_address>
**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)`.
</issue_to_address>| log::info!( | ||
| "[exit] Acquired instances lock for agent cleanup in {}ms", | ||
| lock_start.elapsed().as_millis() | ||
| ); |
There was a problem hiding this comment.
🟡 中等 · Agent 进程在关闭后仍然存活
当另一个线程持有 instances 时发生 panic,cleanup_all_agent_children 会在检查锁结果前记录已获取锁;随后 if let Ok 会因互斥锁已中毒而跳过清理。这样一来,即使 agent 子进程仍在运行,窗口处理程序也可能报告清理已完成。
仅在成功获取锁后记录日志,并报告或处理因锁中毒导致的清理失败,而不是悄悄跳过。
面向 AI agent 的提示
在 `src-tauri/src/commands/types.rs` 第 806-809 行:
**Agent 进程在关闭后仍然存活**
当另一个线程持有 `instances` 时发生 panic,`cleanup_all_agent_children` 会在检查锁结果前记录已获取锁;随后 `if let Ok` 会因互斥锁已中毒而跳过清理。这样一来,即使 agent 子进程仍在运行,窗口处理程序也可能报告清理已完成。
仅在成功获取锁后记录日志,并报告或处理因锁中毒导致的清理失败,而不是悄悄跳过。Original comment in English
🟡 Medium · Agent processes survive shutdown
When another thread panicked while holding instances, cleanup_all_agent_children logs that it acquired the lock before checking the result, then if let Ok skips 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
In `src-tauri/src/commands/types.rs` at lines 806-809:
**Agent processes survive shutdown**
When another thread panicked while holding `instances`, `cleanup_all_agent_children` logs that it acquired the lock before checking the result, then `if let Ok` skips 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.| log::info!( | ||
| "[exit] Window '{}' close requested, minimize_to_tray={}", | ||
| window.label(), | ||
| minimize_to_tray | ||
| ); |
There was a problem hiding this comment.
🟡 中等 · 日志存储缓慢会延迟关闭
当配置的日志目录或其文件系统在关闭事件期间发生卡顿时,目录日志目标会在事件线程上同步写入。因此,log::info! 会在调用 api.prevent_close() 之前阻塞关闭处理,或使 RunEvent::Exit 清理延迟到日志写入完成;因此,日志文件系统卡顿会导致窗口或应用程序退出受阻。
在关闭回调中使用非阻塞日志路径,或以其他方式确保日志写入卡顿不会阻塞事件处理。
另见 src-tauri/src/lib.rs:389-392、src-tauri/src/lib.rs:423。
面向 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 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.
Prompt for AI agents
In `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`.| return true; | ||
| } | ||
|
|
||
| log.info(`[task-stop#${instanceId}] 任务已停止,请求退出应用`); |
There was a problem hiding this comment.
🟡 中等 · 退出标记未写入日志
当应用程序退出时,如果异步文件写入仍在等待中,log.info 会启动文件写入但不会等待其完成,而 exit(0) 可能会在写入完成前终止进程,因此退出前的标记不会出现在持久化日志中。
在调用 exit(0) 之前等待日志写入完成。
面向 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, 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).
Prompt for AI agents
In `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)`.
背景
MaaEnd/MaaEnd#7020:任务链末尾执行关闭游戏 +
MXU_KILLPROC(kill_self)后,MXU 主进程 2~3 分钟无响应才退出。用户日志显示 agent 已在数秒内停止,MaaFramework 在卡顿期间没有任何 API 调用,最终是正常走到
RunEvent::Exit退出的;但退出流程中间没有日志,无法判断卡在
exit(0)之前、窗口销毁,还是 agent 清理抢锁。改动
在退出流程关键节点补充
[exit]日志:stopInstanceTasksAndExitApp调用exit(0)前WindowEvent::CloseRequested(是否最小化到托盘)WindowEvent::Destroyed清理开始 / 结束及耗时cleanup_all_agent_children获取instances锁的等待耗时RunEvent::ExitRequested(退出码)、RunEvent::Exitstd::process::exit前的最终退出码仅新增日志,不改变行为。
AI 使用信息:
🤖 Generated with Claude Code
Sourcery 总结
增强:
Original summary in English
Summary by Sourcery
Enhancements: