Repository navigation
feat(logs): include on-error AVI clips in exports - #406
tianguzhang wants to merge 1 commit into
Conversation
Codex Review SummaryThis 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. |
|
@MistEO 已取消草稿,麻烦有空帮忙审核一下日志导出这部分,重点看看文件收集、体积限制和兼容性。关联框架 PR:MaaXYZ/MaaFramework#1593,讨论:MaaXYZ/MaaFramework#1594。 |
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/file_ops.rs" line_range="662" />
<code_context>
+ let on_error_artifacts = collect_debug_artifacts(
+ &debug_dir.join("on_error"),
+ "on_error",
+ &["png", "jpg", "jpeg", "avi"],
+ );
+ let vision_images =
</code_context>
<issue_to_address>
**Large clips exhaust export memory**
When a large AVI reaches the capacity check and `pre_compress_measure` is called, `pre_compress_measure` buffers the entire deflated clip in a `Vec`, using memory proportional to the clip size and potentially exhausting memory and terminating the export or application.
Measure compressed size without retaining the entire compressed clip in memory.
Also at `src-tauri/src/commands/file_ops.rs:663`.
</issue_to_address>
### Comment 2
<location path="src-tauri/src/commands/file_ops.rs" line_range="662" />
<code_context>
+ let on_error_artifacts = collect_debug_artifacts(
+ &debug_dir.join("on_error"),
+ "on_error",
+ &["png", "jpg", "jpeg", "avi"],
+ );
+ let vision_images =
</code_context>
<issue_to_address>
**AVI clips exceed the volume limit**
When an AVI's compressed ZIP entry exceeds the remaining volume budget, including when it exceeds the limit in a fresh volume, the `wrote_any` guard skips the size check for an empty volume, and `add_file_to_zip` writes the AVI as one entry, producing a ZIP volume larger than `MAX_VOLUME_BYTES` while the export reports success.
Enforce the volume limit for the first entry too, and handle an AVI that cannot fit in an empty volume without writing an oversized volume.
Also at `src-tauri/src/commands/file_ops.rs:663`.
</issue_to_address>
### Comment 3
<location path="src-tauri/src/commands/file_ops.rs" line_range="557" />
<code_context>
- let mut images: Vec<_> = rd.flatten().filter(|e| is_image_file(&e.path())).collect();
+ let mut artifacts: Vec<_> = rd
+ .flatten()
+ .filter(|e| e.path().is_file() && has_extension(&e.path(), extensions))
+ .collect();
</code_context>
<issue_to_address>
**Exports can contain incomplete clips**
When the recorder writes an AVI directly into `debug/on_error` while an export is collecting or copying it, `collect_debug_artifacts` accepts the live AVI path, and `add_file_to_zip` copies it without waiting for the recorder to finish; the ZIP captures a truncated or invalid clip, so the exported video cannot be played reliably.
Only export finalized clips, for example by writing to a temporary path and atomically renaming after the recorder closes the file, or by coordinating export with recorder finalization.
</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/file_ops.rs" line_range="662" />
<code_context>
+ let on_error_artifacts = collect_debug_artifacts(
+ &debug_dir.join("on_error"),
+ "on_error",
+ &["png", "jpg", "jpeg", "avi"],
+ );
+ let vision_images =
</code_context>
<issue_to_address>
**Large clips exhaust export memory**
When a large AVI reaches the capacity check and `pre_compress_measure` is called, `pre_compress_measure` buffers the entire deflated clip in a `Vec`, using memory proportional to the clip size and potentially exhausting memory and terminating the export or application.
Measure compressed size without retaining the entire compressed clip in memory.
Also at `src-tauri/src/commands/file_ops.rs:663`.
</issue_to_address>
### Comment 2
<location path="src-tauri/src/commands/file_ops.rs" line_range="662" />
<code_context>
+ let on_error_artifacts = collect_debug_artifacts(
+ &debug_dir.join("on_error"),
+ "on_error",
+ &["png", "jpg", "jpeg", "avi"],
+ );
+ let vision_images =
</code_context>
<issue_to_address>
**AVI clips exceed the volume limit**
When an AVI's compressed ZIP entry exceeds the remaining volume budget, including when it exceeds the limit in a fresh volume, the `wrote_any` guard skips the size check for an empty volume, and `add_file_to_zip` writes the AVI as one entry, producing a ZIP volume larger than `MAX_VOLUME_BYTES` while the export reports success.
Enforce the volume limit for the first entry too, and handle an AVI that cannot fit in an empty volume without writing an oversized volume.
Also at `src-tauri/src/commands/file_ops.rs:663`.
</issue_to_address>
### Comment 3
<location path="src-tauri/src/commands/file_ops.rs" line_range="557" />
<code_context>
- let mut images: Vec<_> = rd.flatten().filter(|e| is_image_file(&e.path())).collect();
+ let mut artifacts: Vec<_> = rd
+ .flatten()
+ .filter(|e| e.path().is_file() && has_extension(&e.path(), extensions))
+ .collect();
</code_context>
<issue_to_address>
**Exports can contain incomplete clips**
When the recorder writes an AVI directly into `debug/on_error` while an export is collecting or copying it, `collect_debug_artifacts` accepts the live AVI path, and `add_file_to_zip` copies it without waiting for the recorder to finish; the ZIP captures a truncated or invalid clip, so the exported video cannot be played reliably.
Only export finalized clips, for example by writing to a temporary path and atomically renaming after the recorder closes the file, or by coordinating export with recorder finalization.
</issue_to_address>| let on_error_artifacts = collect_debug_artifacts( | ||
| &debug_dir.join("on_error"), | ||
| "on_error", | ||
| &["png", "jpg", "jpeg", "avi"], |
There was a problem hiding this comment.
🟡 中等 · 大型片段会耗尽导出内存
当大型 AVI 触发容量检查并调用 pre_compress_measure 时,pre_compress_measure 会将整个压缩后的片段缓冲到一个 Vec 中,所需内存与片段大小成正比,可能导致内存耗尽并终止导出或应用程序。
请在测量压缩大小时避免将整个压缩后的片段保留在内存中。
另见 src-tauri/src/commands/file_ops.rs:663。
提供给 AI 代理的提示
在 `src-tauri/src/commands/file_ops.rs` 第 662 行:
**大型片段会耗尽导出内存**
当大型 AVI 触发容量检查并调用 `pre_compress_measure` 时,`pre_compress_measure` 会将整个压缩后的片段缓冲到一个 `Vec` 中,所需内存与片段大小成正比,可能导致内存耗尽并终止导出或应用程序。
请在测量压缩大小时避免将整个压缩后的片段保留在内存中。
另见 `src-tauri/src/commands/file_ops.rs:663`。Original comment in English
🟡 Medium · Large clips exhaust export memory
When a large AVI reaches the capacity check and pre_compress_measure is called, pre_compress_measure buffers the entire deflated clip in a Vec, using memory proportional to the clip size and potentially exhausting memory and terminating the export or application.
Measure compressed size without retaining the entire compressed clip in memory.
Also at src-tauri/src/commands/file_ops.rs:663.
Prompt for AI agents
In `src-tauri/src/commands/file_ops.rs` at line 662:
**Large clips exhaust export memory**
When a large AVI reaches the capacity check and `pre_compress_measure` is called, `pre_compress_measure` buffers the entire deflated clip in a `Vec`, using memory proportional to the clip size and potentially exhausting memory and terminating the export or application.
Measure compressed size without retaining the entire compressed clip in memory.
Also at `src-tauri/src/commands/file_ops.rs:663`.| let on_error_artifacts = collect_debug_artifacts( | ||
| &debug_dir.join("on_error"), | ||
| "on_error", | ||
| &["png", "jpg", "jpeg", "avi"], |
There was a problem hiding this comment.
🟡 中等 · AVI 片段会超出卷大小限制
当 AVI 的压缩 ZIP 条目超出卷的剩余容量预算时(包括在新卷中超出限制的情况),wrote_any 守卫会跳过对空卷的大小检查,而 add_file_to_zip 会将 AVI 作为单个条目写入,导致 ZIP 卷超过 MAX_VOLUME_BYTES,但导出仍报告成功。
首个条目也应遵守卷大小限制;如果 AVI 无法放入空卷,请妥善处理,不要写出超限的卷。
另见 src-tauri/src/commands/file_ops.rs:663。
提供给 AI 代理的提示
在 `src-tauri/src/commands/file_ops.rs` 第 662 行:
**AVI 片段会超出卷大小限制**
当 AVI 的压缩 ZIP 条目超出卷的剩余容量预算时(包括在新卷中超出限制的情况),`wrote_any` 守卫会跳过对空卷的大小检查,而 `add_file_to_zip` 会将 AVI 作为单个条目写入,导致 ZIP 卷超过 `MAX_VOLUME_BYTES`,但导出仍报告成功。
首个条目也应遵守卷大小限制;如果 AVI 无法放入空卷,请妥善处理,不要写出超限的卷。
另见 `src-tauri/src/commands/file_ops.rs:663`。Original comment in English
🟡 Medium · AVI clips exceed the volume limit
When an AVI's compressed ZIP entry exceeds the remaining volume budget, including when it exceeds the limit in a fresh volume, the wrote_any guard skips the size check for an empty volume, and add_file_to_zip writes the AVI as one entry, producing a ZIP volume larger than MAX_VOLUME_BYTES while the export reports success.
Enforce the volume limit for the first entry too, and handle an AVI that cannot fit in an empty volume without writing an oversized volume.
Also at src-tauri/src/commands/file_ops.rs:663.
Prompt for AI agents
In `src-tauri/src/commands/file_ops.rs` at line 662:
**AVI clips exceed the volume limit**
When an AVI's compressed ZIP entry exceeds the remaining volume budget, including when it exceeds the limit in a fresh volume, the `wrote_any` guard skips the size check for an empty volume, and `add_file_to_zip` writes the AVI as one entry, producing a ZIP volume larger than `MAX_VOLUME_BYTES` while the export reports success.
Enforce the volume limit for the first entry too, and handle an AVI that cannot fit in an empty volume without writing an oversized volume.
Also at `src-tauri/src/commands/file_ops.rs:663`.| let mut images: Vec<_> = rd.flatten().filter(|e| is_image_file(&e.path())).collect(); | ||
| let mut artifacts: Vec<_> = rd | ||
| .flatten() | ||
| .filter(|e| e.path().is_file() && has_extension(&e.path(), extensions)) |
There was a problem hiding this comment.
🟡 中等 · 导出内容可能包含不完整的片段
当导出正在收集或复制 AVI 时,录制器直接将 AVI 写入 debug/on_error,collect_debug_artifacts 会接受这个仍在写入的 AVI 路径,而 add_file_to_zip 不会等待录制器完成就将其复制;因此 ZIP 中会包含被截断或无效的片段,导致导出的视频无法可靠播放。
只导出已完成的片段。例如,可以先写入临时路径,并在录制器关闭文件后原子重命名;也可以在导出与录制器完成写入之间进行协调。
提供给 AI 代理的提示
在 `src-tauri/src/commands/file_ops.rs` 第 557 行:
**导出内容可能包含不完整的片段**
当导出正在收集或复制 AVI 时,录制器直接将 AVI 写入 `debug/on_error`,`collect_debug_artifacts` 会接受这个仍在写入的 AVI 路径,而 `add_file_to_zip` 不会等待录制器完成就将其复制;因此 ZIP 中会包含被截断或无效的片段,导致导出的视频无法可靠播放。
只导出已完成的片段。例如,可以先写入临时路径,并在录制器关闭文件后原子重命名;也可以在导出与录制器完成写入之间进行协调。Original comment in English
🟡 Medium · Exports can contain incomplete clips
When the recorder writes an AVI directly into debug/on_error while an export is collecting or copying it, collect_debug_artifacts accepts the live AVI path, and add_file_to_zip copies it without waiting for the recorder to finish; the ZIP captures a truncated or invalid clip, so the exported video cannot be played reliably.
Only export finalized clips, for example by writing to a temporary path and atomically renaming after the recorder closes the file, or by coordinating export with recorder finalization.
Prompt for AI agents
In `src-tauri/src/commands/file_ops.rs` at line 557:
**Exports can contain incomplete clips**
When the recorder writes an AVI directly into `debug/on_error` while an export is collecting or copying it, `collect_debug_artifacts` accepts the live AVI path, and `add_file_to_zip` copies it without waiting for the recorder to finish; the ZIP captures a truncated or invalid clip, so the exported video cannot be played reliably.
Only export finalized clips, for example by writing to a temporary path and atomically renaming after the recorder closes the file, or by coordinating export with recorder finalization.
Include AVI clips from
debug/on_errorin exported log archives, alongside the existing error screenshots. AVI extensions are matched case-insensitively;visionremains image-only and the existing filters for other debug files are unchanged.The same modification-time ordering, archive splitting, and export retention rules apply. No encoder or new runtime dependency is introduced.
Validation:
cargo check --locked --offline,cargo fmt --check, and a temporary Rust regression harness exercising the production collection and ZIP-writing functions. The harness first reproduced missing AVI files, then verified AVI inclusion, exclusions, ordering, retention, and two-volume ZIP splitting. A 30-second MJPEG AVI also survived a byte-identical ZIP round-trip and was checked with ffprobe. Temporary tests are not included in this PR.Draft companion to MaaEnd/MaaEnd#6944 while the recorder implementation and end-to-end validation are in progress.
Sourcery 摘要
将发生错误时生成的 AVI 片段纳入导出的日志归档,同时不改变现有的调试文件筛选规则或导出行为。
新功能:
debug/on_error中的 AVI 片段与受支持的错误图像一同纳入导出的日志归档,并以不区分大小写的方式匹配扩展名。改进:
Original summary in English
Summary by Sourcery
Include on-error AVI clips in exported log archives without changing existing debug-file filters or export behavior.
New Features:
debug/on_errorin exported log archives alongside supported error images, with case-insensitive extension matching.Enhancements: