10 · Optimize 任务编排
Optimize 最有价值的设计不是维护命令清单,而是让每个任务必须报告一个可解释、可汇总的状态。
21 个任务的声明式目录
catalog.sh 用六组对齐数组注册 action、handler、健康名称、白名单名称、说明与自动执行安全标志。选择数组而非关联数组是为了兼容 macOS 自带 Bash 3.2。
加载时目录自检:字段数量必须对齐,action/handler 名称匹配格式,元数据不能为空,自动任务必须显式标记 safe,action 与 handler 不得重复。一个注册错误会在运行任何维护动作前失败。
任务覆盖 DNS/Spotlight、Finder 缓存、旧 saved state、偏好修复、SQLite vacuum、LaunchServices、网络栈、权限、周期维护、磁盘验证、登录项审计等。
运行前诊断不是盲目优化
入口先生成健康 JSON,展示 RAM、磁盘与 uptime,再对进程家族做两次 CPU 采样。只有两次都越过阈值才报告 sustained bottleneck。对 syspolicyd 压力,还会检查挂载镜像,区分系统管理的 CoreSimulator 镜像与真正可建议卸载的 DMG。
这避免用一次瞬时尖峰触发“优化建议”,也避免把正常的系统模拟器卷当成故障。
一次授权,逐项降级
Dry run 中所有任务展开以供检查;真实运行只集中请求一次 sudo。用户拒绝后,MOLE_OPTIMIZE_SUDO_AVAILABLE=false,需要管理员权限的任务返回 skipped,其他用户级任务仍继续。
白名单也在 dispatcher 统一处理:被豁免任务仍经历 start/result/finish,结果为 skipped,确保最终计数完整。
六态结果模型
| 状态 | 含义 |
|---|---|
applied | 已改变,或 dry-run 中将改变 |
unchanged | 检查完成,无需改变 |
skipped | 策略或上下文主动阻止 |
unavailable | 宿主机不具备能力 |
attention | 发现问题,需要用户处理 |
failed | 符合条件但操作失败 |
optimize_task_start、result、finish 构成小状态机:一个任务只能设置一次结果,未设置结果不能结束,同一 action 不能重复记录。子操作计数中只要有一次符合条件的操作失败,整个任务就是 failed,不能被另一个成功步骤掩盖。
循环结束后,结果数必须等于目录任务数。最终 summary 分别显示 applied、unchanged、skipped、unavailable、attention、failed;进程成功与否由 failed 数量决定。
安全任务也需要上下文守卫
网络栈刷新会识别系统 VPN 与默认路由上的 utun,不因任意 utun 接口就过度跳过;SQLite vacuum 在 Mail/Safari/Messages 运行时跳过;Spotlight 重建检查电源与实际状态;登录项审计只报告损坏项,让用户去系统设置删除。
“目录中标记 safe”表示处理器实现了这些前提,不表示动作在任何时间都无条件安全。
关键源码索引
bin/optimize.sh#L188-L309:健康采集、sudo 与任务循环。lib/optimize/catalog.sh:任务目录与加载时校验。lib/optimize/outcomes.sh:六态结果状态机。lib/optimize/tasks.sh#L1748-L1773:统一 dispatcher。lib/optimize/diagnostics.sh#L353-L430:持续 CPU 诊断。
下一章进入 Go 侧,观察 Analyze 如何把昂贵磁盘扫描变成可中断、可缓存、不会乱跳的终端交互。