fix(amsg-client): subscribePush() 认出并重订死 endpoint,不再返回一个推不通的订阅 - #48
Merged
Conversation
刚 unsubscribe() 过又马上 subscribe() 时,Chromium 那边旧订阅的待删除标记还没清 干净,这段窗口期里它不去推送服务要新地址,而是给一个 https://permanently-removed.invalid/... 的占位订阅。.invalid 是 RFC 2606 保留顶级 域,永不解析。这种订阅有 endpoint、有密钥、getSubscription() 也认得,之前会被原样 返回并登记到服务端:用户看到「订阅成功」,两边都不报错,到点推送全挂。 - 拿到占位订阅就退掉它,等浏览器清完标记再重订,最多三次(间隔 800ms、1600ms) - 三次仍是占位订阅时抛 err.code === 'PUSH_ENDPOINT_ZOMBIE',err.details 带 { attempts, endpoint }。SDK 不产出面向终端用户的提示文案,交给接入方决定 - pushManager.subscribe() 自己抛的错原样往外抛、不重试:那是权限 / 能力问题 - 第一次就拿到活 endpoint 时只调一次 subscribe()、不产生额外等待,与之前一致 回归测试钉住四条:首次即活只订一次;首次占位二次活的返回活的且占位那条被退订; 三次全占位抛 PUSH_ENDPOINT_ZOMBIE 且退避为 800/1600;subscribe() 抛错时只调一次。 退避走可注入的 sleep seam,测试不吃真实等待。 Claude-Session: https://claude.ai/code/session_01T6Z3bzeKPu6jHyVuM3SuyW
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.
问题
刚
unsubscribe()过又马上subscribe()时,Chromium 那边旧订阅的待删除标记还没清干净。这段窗口期里它不去推送服务要新地址,而是直接给一个https://permanently-removed.invalid/...的占位订阅——.invalid是 RFC 2606 保留顶级域,全球 DNS 永不解析。这种订阅结构上完全正常:有 endpoint、有密钥、
getSubscription()也认得。之前subscribePush()拿到什么返回什么,于是这个死地址会被一路登记到服务端。表现是最难查的那一种——用户看到「订阅成功」,服务端也存下了,两边都没有任何报错,只是到点什么都收不到。改后
subscribe(),无额外等待,行为不变)permanently-removed.invalid占位订阅err.code === 'PUSH_ENDPOINT_ZOMBIE',err.details为{ attempts, endpoint }pushManager.subscribe()自己抛错subscribePush()的契约由此变成「给你一个 endpoint 活着的订阅」,拿到就能直接登记。只给机制,不给文案
这是通用 SDK,错误里不塞面向终端用户的提示语——那句话该怎么说、用什么语言、要不要引导用户换浏览器,跟具体产品和用户群有关,由接入方自己决定。这里只给一个可程序化判定的
err.code,让下游能把「这是僵尸 endpoint」和「别的订阅失败」分开处理。测试
packages/rei-standard-amsg/client/test/push-subscription.test.mjs补四条回归守卫:首次即活只订一次;首次占位二次活的返回活的且占位那条被退订;三次全占位抛PUSH_ENDPOINT_ZOMBIE且退避为 800/1600;subscribe()抛错时只调一次。另加一条「占位那条退订失败也照样重试」。退避走可注入的 sleep seam(沿用
agentic-fire.js的_agenticSleep写法),测试不吃真实等待。全 workspace
npm test:743 通过 / 0 失败。https://claude.ai/code/session_01T6Z3bzeKPu6jHyVuM3SuyW