Skip to content

feat(sidecar): write per-file metadata on open and finalise on close (D4-B) - #19

Merged
wt159 merged 2 commits into
mainfrom
feat/d4-sidecar-b
Nov 9, 2026
Merged

wt159 merged 2 commits into
mainfrom
feat/d4-sidecar-b

Conversation

@wt159

@wt159 wt159 commented Nov 9, 2026

Copy link
Copy Markdown
Owner

按 implement-spec 流程跑完 D4-B:工单 #17(原子落盘 + 开关)与 #18(生命周期钩子)在同一集成分支上实现、评审、合并。

行为

  • file_info_t 持有一份自包含的元数据副本——写线程不会被通知"句柄被 LRU 回收了",所以关闭钩子不能依赖 session 还活着。
  • 文件创建时写首版(complete=false);所有关闭路径都 finalize:显式 stop、2 秒 rollover、1GB 分片、LRU 回收、模块销毁。
  • 开关默认关闭,采样时机是"文件打开时",与设计 §10.1 一致。

评审发现并修掉的问题

  1. 重开会把已完成的 sidecar 降级:LRU 回收后 append 重开,attach 又写了一次首版,把 complete=true + total_bytes 覆盖成 complete=false。改为只在 is_new 时写首版。
  2. 重开丢失原始开始时间:start_time_unix_ms 变成重开时刻。改为在 session 上保留 file_start_unix_ms,只有 rollover/分片才清零。
  3. fclose 失败仍标记 complete:可能被截断的文件被标成完整。改为关闭失败则跳过 finalize。
  4. 开关策略分层错位:sidecar_write_meta 内部读开关,导致"打开时开、中途关掉"的文件无法收尾。策略上移到调用点。
  5. 文档同步:AGENTS 的公开 API 清单、设计文档状态行。

测试

  • sidecar lifecycle on real file:开开关 + write_ex → .json 存在、complete=true、total_bytes 等于 .pcm 实际大小、sample_rate 正确
  • legacy write leaves no sidecar:开关开着,旧接口也不产生 .json
  • disabled metadata leaves no sidecar:关开关 + write_ex → 无 .json
  • sidecar switch state:开关读写

未覆盖(已知)

  • LRU 回收后补全的端到端用例:需要同时跨越 1s 空闲阈值与 2s rollover 窗口,CI 上不稳定,之前已因此删过一次用例。该路径由共享的 finalize_slot_meta() 覆盖,静态审查过。
  • S-04 分片、S-05 rollover、S-06 被杀、S-08 只读目录:留到 D4-C。

Android HAL

旧接口不传格式 → 不 attach → 不产生任何 .json,字节输出不变。开关默认 0,Android 侧零调用零开销。

Closes #17
Closes #18

wt159 added 2 commits November 9, 2026 18:32
D4-B of the sidecar spec (#17, #18).

- sidecar_write_file stages <name>.json.tmp and renames it into place, so a
  reader never sees a partial file; the switch is a process-wide atomic and
  defaults to off.
- file_info_t carries a self-contained metadata copy: the writer is not told
  when the file manager evicts a handle, so the closing hook cannot rely on the
  session still being alive.
- The initial version is written when a file is created; every close path
  (explicit stop, rollover, size split, LRU eviction, teardown) finalises it
  with total_bytes and end time.
- A reopen after eviction keeps the completed sidecar and only refreshes it on
  close; the original start time survives on the session.
- A failed fclose skips finalisation instead of marking a possibly truncated
  file as complete.

Old call sites pass no format, so they never produce a sidecar and the .pcm
output is unchanged.
whitebox.c includes file_mgr.c and dump_pcm_data.c, so every new external
symbol needs a rename or it collides with the compiled translation units at
link time.
@wt159
wt159 merged commit 43acfec into main Nov 9, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

D4-B2: file_mgr 生命周期钩子与 sidecar 接线 D4-B1: sidecar 原子落盘与运行时开关

1 participant