ECHO Next Native Worker Ready Architecture
Library Core v0.1 从设计上就预留了 native worker 接口。TypeScript 管编排、SQLite、IPC 校验、分页 API、扫描任务和面向 UI 的业务规则;重活通过稳定的 worker 接口调用,以后 Rust 或 C++ 可以替换首批 TS 实现,而不用动 Renderer、IPC 或 SQLite schema。
曲库重活(读标签、抽封面、扫文件夹)怎么分层,以及以后怎么无痛换成原生实现。技术细节多,但核心就一句:接口稳定,实现可换。
Worker 边界
Section titled “Worker 边界”稳定接口在 src/main/library/workers/ 下:
MetadataReader.read(filePath) -> MetadataResultCoverExtractor.extract(filePath, options) -> CoverResultFileScanner.scanFolder(folderPath, options) -> AsyncIterable<ScannedFile>
当前实现:
TsMetadataReader:music-metadata,优先读嵌入标签,缺字段才用文件名/文件夹兜底TsCoverExtractor:TS+sharp v0.2 封面 worker;嵌入封面、同目录 cover/front/folder 图、生成默认图、磁盘缓存路径、真实 resize 输出TsFileScanner:递归枚举文件并 stat
以后可以换成:
RustMetadataWorkerRustCoverWorkerRustFileScanner
LibraryService 和 ScanJobQueue 依赖接口,不依赖 TS 具体类。Renderer 和 preload 不知道当前跑的是哪套 worker。
稳定返回结构
Section titled “稳定返回结构”MetadataResult 包含:
- 规范化 metadata 字段
fieldSources- 有的话带上嵌入封面字节,给 cover worker 用
warningserrorsstatus
CoverResult 包含:
sourcethumbPathalbumPathlargePathoriginalRefsourceHashmimeTypewarningserrors
ScannedFile 包含:
pathsizeBytesmtimeMs
这些结构是 native worker 必须遵守的契约。原始解析细节可以留在 worker 结果里做诊断,但 Renderer 列表 API 收不到它们。
Rust/C++ 优先级
Section titled “Rust/C++ 优先级”原生化的优先顺序:
CoverWorker:只有 TS+sharp v0.2 实测达不到封面生成目标时,才最高优先。MetadataWorker:第二优先;大曲库上标签解析可能变贵。FileScanner:只有 3000/10000 曲压力测试证明 TS 目录遍历是瓶颈时,才上 Rust/C++。
音频输出已经在走同一条路,通过 echo-audio-host。
TypeScript 服务层:
- 创建扫描任务
- 检查增量缓存 key
- 带并发限制调度 worker 调用
- 事务写 SQLite
- 持久化专辑和艺术家索引
- 暴露分页、IPC 安全的结果
Worker 层:
- 读标签
- 提取/缓存封面;当前 TS+sharp v0.2 用
sharp做 resize,优先级和缓存调度仍由 TypeScript 管 - 枚举文件和 stat 数据
IPC:
- 校验输入
- 调用
LibraryService - 不跑 SQL、不解析 metadata、不抽封面、不扫文件夹
Renderer:
- 调 typed preload 方法
- 渲染分页的 tracks/albums/folders/status
- 不分组专辑、不生成封面、不扫文件、不把全库塞进内存
Phase 1 和 Phase 1.5 验证目标:
- 应用启动不能扫全库
getTracks首页目标:200 ms 以内getAlbums首页目标:300 ms 以内- 未变化文件的扫描跳过率应接近 100%
- 封面缩略图在扫描时生成,不在 UI 滚动时生成
- 专辑墙重启后读持久化的
albums行 getTracks和getAlbums永远不返回完整封面 binary/base64- 扫描任务后台跑,且可取消
- metadata 和 cover worker 有并发限制
- 大曲库不能因为专辑墙在渲染就把 CPU 顶到 50% 附近
Phase 1.5 验证
Section titled “Phase 1.5 验证”Phase 1.5 Native Worker & Performance Validation:
- 决定要不要上 native worker 前,先用 Phase 1.1 的
library.getDiagnostics()、烟测和npm run benchmark:library结果 - 只有实测证明封面提取/缓存生成是瓶颈时,才做 Go/C#/Rust
CoverWorker - 评估 Rust
MetadataWorker - 跑 3000 和 10000 曲压力测试,以及 3000 和 10000 专辑墙压力测试
- 记录 CPU、内存、总扫描时间、metadata 时间、封面时间、专辑墙加载时间
- 用数据决定
FileScanner要不要 Rust/C++ - 验证换 worker 不改变 Renderer、IPC、SQLite schema 或列表 payload
Native CoverWorker 决策信号:
- 生成 1000 张专辑缩略图时 CPU 长时间高于 50%
- 生成 3000 或 10000 张封面时内存峰值不可接受
- Electron 里
sharp打包或 native rebuild 不稳定 thumb.webp和album.webp已经有了,封面缓存命中仍然慢