fix: 冷启动后台卡死导致代理失效与弹窗空白 (#276)#327
Open
hughcube wants to merge 2 commits into
Open
Conversation
On Manifest V3 the background service worker may still be asleep or initializing when the popup is opened right after a browser restart. The popup's first getState message then fails with chrome.runtime.lastError and no response is delivered. The omegaTarget.state() wrapper only resolved its deferred inside .then(), with no rejection handler, so a single missed response left the deferred unsettled forever: the popup stayed blank, showing only the toolbar icon, with no way to recover except reloading the extension. - Retry callBackground() a few times with a small backoff when sendMessage fails with chrome.runtime.lastError, to ride out the service-worker wake-up race. - Propagate rejections in omegaTarget.state() so a permanently failed call rejects the promise instead of hanging silently. Closes zero-peak#276
…o-peak#276) On a service-worker cold start, Options#init awaited a state (IndexedDB) read BEFORE applying a profile. When that read stalls (which happens on cold starts), options.ready never resolved: applyProfile never ran so the proxy was never configured, and the popup never got a getState reply so it stayed blank ("only an icon"), until the extension was reloaded by hand. Wrap startup in a timeout. If loadOptions plus applying the initial profile does not finish in time, fall back to applying the configured startup profile (or the fallback profile) so the proxy gets set and ready resolves. Add a deterministic regression test that simulates a stalling state read.
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.
问题 (Closes #276)
在 Chrome 刚打开(冷启动)时,扩展经常只剩一个工具栏图标:弹窗加载不出来、点击无响应,整个代理也一并失效,必须手动在
chrome://extensions里 reload 插件才能恢复。根因
后台 service worker 的
Options#init(omega-target/src/options.coffee)在应用情景模式(设置chrome.proxy.settings)之前,会先await一次state(IndexedDB)读取。在 MV3 service worker 冷启动时,这次 IndexedDB 读取有时会永久挂起,于是:options.ready永不 resolve →applyProfile从不执行 → 代理从未被设置(整体失效);getState消息 → 弹窗一直空白("只剩图标")。两个症状同源,都卡在这次挂起的存储读取上。
修复
1. 后台根治 (
omega-target/src/options.coffee)给启动流程加一道超时保险:若
loadOptions+ 应用初始情景在限定时间(默认 5s)内没完成,就用配置的「启动情景」或兜底情景强制把代理设上,并让options.readyresolve。这样任何启动期存储读取挂起都不会再让代理和弹窗一起卡死。2. 弹窗自愈 (
omega-target-chromium-extension/src/coffee/omega_target_web.coffee)callBackground在chrome.runtime.lastError(service worker 尚未唤醒/就绪)时做有限次重试与退避,并让state()的 promise 正确传播拒绝,避免一次消息失败就让弹窗永久挂起。测试
新增
omega-target/test/options_startup.coffee:用一个"读取永不返回"的state确定性模拟冷启动挂起,断言修复后仍能applyProfile且ready会 settle(无需浏览器/网络/凭据即可复现并验证)。副作用
正常启动只需几十~几百毫秒,远不到超时阈值,超时分支不会触发,行为与改前一致。仅在"启动卡死"这一异常场景才介入:先用启动/兜底情景保证浏览器可用,待挂起的读取最终返回后原流程会再应用真正的情景(
chrome.proxy.settings幂等,最终一致)。