SuperAPI AI 工具集

dual-mode-persist-blocking-or-async

编程与开发

查看项目

更新于 10-17 16:15

技能介绍

用途:解决持久化逻辑存在两类调用方、需求相反的问题。周期性保存发生在对象存活期间,不能阻塞任何流程;teardown(释放)保存发生在对象被释放时,它要 launch 的作用域马上就要被取消,若仍用 fire-and-forget 方式写入,写入会直接丢失。

主要能力:给出一种“写一次函数体、由调用方选择执行方式”的模式。接口为 fun mayBeSaveState(runBlocking: Boolean = false),实现里先把保存步骤包成 suspend 块(检查 saveStateEnabled、跳过 item 未知或集合重建中的窗口、写入设置与集合),再用 if (runBlocking) runBlocking { unit() } else scope.launch { unit() } 分派。释放路径调用 mayBeSaveState(true),并把它放在移除监听器、取消协程作用域之前。

使用方式与陷阱说明:条目以代码示例和 grep 命令辅助检查调用点,例如 grep -rn "mayBeSaveState(true)|mayBeSaveState(runBlocking = true)" --include="*.kt" src/,要求每个命中都是真正的 teardown 路径。还指出:默认值 false 让既有调用保持异步,也使误传 true 难以在评审中发现;参数名 runBlocking 与协程构建器同名会造成遮蔽和误读,建议按意图命名(如 awaitCompletion、synchronous);拆分函数体会出现守卫漂移,轻量周期保存缺少集合状态检查,只有它只写位置字段时才可接受;守卫应在执行时读取状态,而非调用时快照;teardown 中的顺序必须保持,保存要在资源释放前执行;主线程上的 runBlocking 仍会阻塞,因此函数体必须保持小而快,且不得包含网络调用。

验证方法:在状态变化中途强杀进程再重启,恢复状态应对应被杀瞬间而非上次周期保存;再做一次干净退出,确认两条路径结果一致。给共享函数体入口与完成各加一行日志,触发干净关闭,两行都应在取消作用域的代码之前出现。

适用场景:Kotlin 协程项目中同时存在周期性状态保存与释放前最终保存的组件,例如播放器状态、设置持久化等。限制:需要自行控制函数体规模与调用点枚举;资料未提供更多平台、依赖或安装信息。