[DRAFT] 🐛 异步 GM.getValue/getValues/listValues 确保读取最新 values(#950 重设计)#1626
Draft
cyfung1031 wants to merge 1 commit into
Draft
[DRAFT] 🐛 异步 GM.getValue/getValues/listValues 确保读取最新 values(#950 重设计)#1626cyfung1031 wants to merge 1 commit into
cyfung1031 wants to merge 1 commit into
Conversation
重新设计自 scriptscat#950:valueDAO 在每次值变更时以严格递增的 updatetime 记录版本,valueUpdate 推送携带该 updatetime;页面端异步 GM.* 读取前经 internalApiWaitForFreshValueState 取得当前 updatetime,未同步时 等待对应 valueUpdate 到达后才读取本地缓存,避免读到过期值或次序错乱。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Checklist / 检查清单
GM.getValue/getValues/listValues可能读到过期本地缓存的问题背景
按 #950 的想法在当前 main 分支代码上重新设计。原问题(#898 / #950):页面端 GM values 走本地缓存,其他 tab / 环境写入后经
valueUpdate异步推送同步,异步的GM.getValue/GM.getValues/GM.listValues在推送到达前读取会返回过期值,且与valueUpdate竞争时列表次序可能错乱。#950 基于 release/v1.3 的旧推送通道(
chrome.tabs.sendMessage逐 tab 推送),包含按 storageName 批量合并任务等大规模重构。当前 main 已改为chrome.storage.session(valueUpdateDelivery)单通道广播并经runtime.pushValueUpdate统一推送,原 diff 无法套用;本 PR 保留其核心思路,以最小侵入方式落在现行架构上。本次改动
ValueUpdateDataEncoded新增updatetime字段:valueDAO中该 storageName 当前的更新时间戳,随每条valueUpdate推送到各执行环境。ValueService.setValues:值变更时以aNow()(严格递增)刷新valueModel.updatetime并随推送携带;值未变更时也携带当前updatetime。ValueService.waitForFreshValueState:id非空时先执行一次空setValues,借同一条valueUpdate推送通道把当前updatetime(连同id)送达调用方页面;返回valueDAO当前updatetime(读取经同一stackAsyncTask队列,避免读到写入中途状态)。internalApiWaitForFreshValueState(default: true,不对应任何@grant)。GM.getValue/GM.getValues/GM.listValues读取前先经waitForFreshValueState同步:valueUpdate(valueDaoUpdatetime为undefined)时,附带id触发上述空setValues回推;updatetime比本环境已同步时点新时,登记readFreshes等待对应valueUpdate到达后才读取本地缓存。GM_getValue等)行为不变。_GM_setValue/_GM_setValues重复的 id 生成抽为generateValChangeId(waitForFreshValueState也需要)。实现考虑
updatetime每次变更严格递增(aNow()),客户端只需等待「收到updatetime >= 服务端返回值的valueUpdate」即可确认本地缓存不旧于调用时点的 DAO 状态;readFreshes按updatetime >= t批量放行,推送合并/跳变也不会悬挂。valueUpdate推送通道(storage.session 广播),天然与值变更推送保持全序,无需新增消息类型或改动runtime.pushValueUpdate/ sandbox / offscreen 转发链。message不可用或 extension context invalidated 时(sendMessage返回undefined),清理挂起的id回调并直接读本地缓存,不会永久挂起。valueUpdateTasks/ValueUpdateSendData):那是性能与旧通道次序问题的重构,当前 main 的stackAsyncTask(cacheKey)序列化已保证写入与推送次序,为控制风险与 diff 范围不搬入。已知限制
setValues+ 回推),之后仅在检测到落后时才等待;这是「保证读到最新值」的固有成本。valueUpdate推送本身丢失(delivery 通道异常),等待方会依赖后续任意一次推送放行;推送可靠性问题不在本 PR 范围。建议审查重点
waitForFreshValueState(content 端)在并发调用、context 失效、updatetime === 0(无 value model)各路径下不悬挂、不早读。setValues中updatetime在「新建 / 变更 / 未变更」三分支的取值。internalApiWaitForFreshValueState使用default: true的权限面:仅回推本脚本自身 storage 的时间戳与空 entries,不泄露值内容。关联
验证
pnpm run test:ci:309 files / 3440 tests 全部通过。pnpm run lint(prettier + tsc + check:i18n + eslint):通过。GM.getValue/getValues/listValues会发出internalApiWaitForFreshValueState并等待回推;updatetime落后时在对应valueUpdate到达前不完成、到达后读到新值;message无效时直接返回本地缓存。setValues刷新并携带updatetime(含未变更分支);waitForFreshValueState带/不带id的行为。🤖 Generated with Claude Code