Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix: improve offscreen messaging reliability for concurrent detection#201

Merged
timerring merged 1 commit intomainfrom
dev
Feb 21, 2026
Merged

fix: improve offscreen messaging reliability for concurrent detection#201
timerring merged 1 commit intomainfrom
dev

Conversation

@timerring
Copy link
Member

Summary

This PR addresses a race condition in the offscreen document messaging layer where concurrent chrome.runtime.sendMessage calls could receive mixed-up or lost responses. It introduces a serialized message queue with readiness polling and timeout protection for all offscreen communication. Additionally, Cnblogs login detection is migrated from a manual cookie-header approach in the service worker to an offscreen document fetch, which sends cookies automatically via document context.

Related Issue

N/A

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Performance improvement
  • Code refactoring
  • Other (please describe):

Changes Made

  • apps/extension/src/background.js: Removed the _offscreenCreated boolean flag; replaced with chrome.offscreen.hasDocument() check on every call. Added _waitForOffscreenReady() ping loop and sendOffscreenMessage() serialization queue. Refactored warmUpFetch and offscreenApiFetch to use sendOffscreenMessage. Added retry logic (up to 2 attempts) for detectCto51ViaOffscreen. Added new detectCnblogsViaOffscreen function.
  • apps/extension/src/offscreen.js: Added OFFSCREEN_PING handler that immediately returns { pong: true }. Added OFFSCREEN_DETECT_CNBLOGS handler calling handleDetectCnblogs(). Added credentials: 'include' to the handleDetectCto51 fetch. Added debug info (status, url, htmlLen, title) to the not-logged-in response of handleDetectCto51. Implemented new handleDetectCnblogs() fetching account.cnblogs.com/user/userinfo with credentials: 'include'.
  • packages/detection/src/platforms/cnblogs.js: Rewrote detectCnblogsUser to delegate to globalThis.__coseDetectCnblogs() (offscreen) instead of manually collecting cookies and attaching them as a Cookie header in a service worker fetch.
  • packages/detection/src/platforms/cto51.js: Added pass-through of _debug info when 51CTO reports not-logged-in, surfacing response metadata for easier diagnosis.

Implementation Details

Key Changes:

  • sendOffscreenMessage(msg, timeoutMs = 15000) — chains each call onto _offscreenQueue so only one offscreen message is in-flight at a time. A Promise.race against a 15 s timeout prevents the queue from getting permanently stuck if the offscreen document is garbage-collected or fails to respond. Errors are swallowed from the queue chain so a single failure does not block future messages.
  • _waitForOffscreenReady(timeoutMs = 3000) — after createDocument resolves, polls by sending OFFSCREEN_PING every 50 ms until the offscreen listener replies { pong: true } or the timeout elapses, ensuring messages are not sent before the listener is registered.
  • Cnblogs offscreen fetch uses credentials: 'include' in document context, making session cookies available automatically — eliminating the brittle manual Cookie header construction that was previously required in the MV3 service worker.

Technical Notes:

  • chrome.runtime.sendMessage is broadcast-based; when multiple offscreen message types are dispatched concurrently, responses can be routed to the wrong caller. The serialization queue is the minimal fix without restructuring the entire messaging architecture.
  • The _offscreenCreated flag was unreliable because it was set to true even in the catch block, preventing recovery after a failed createDocument. The new approach re-checks hasDocument() on every call, which is the correct pattern.
  • 51CTO handleDetectCto51 now explicitly passes credentials: 'include' to ensure consistent cookie behavior across Chrome versions.

Testing

Testing Checklist

  • I have tested this code locally
  • All existing tests pass
  • I have added tests for new functionality
  • I have tested on the affected platform(s)
  • I have verified the changes work in the target browser(s)

Manual Testing Steps

  1. Load the extension in Chrome with the dev branch build
  2. Navigate to a Cnblogs-authenticated session and trigger detection — verify login state is correctly detected via the offscreen path
  3. Trigger concurrent detection calls (e.g., open multiple tabs or rapidly reload) and confirm no mixed-up or missing responses appear in the background service worker console
  4. Verify OFFSCREEN_PING / pong handshake appears in the console on first offscreen document creation
  5. Check 51CTO detection still works and _debug info is logged when not logged in

Screenshots/Videos

N/A

Reviewer Checklist

  • Code follows the project's style guidelines
  • Changes are well-documented
  • No breaking changes or clearly documented if present
  • Security implications have been considered
  • Performance impact has been evaluated
  • All discussions have been resolved

Additional Notes

The sendOffscreenMessage queue is a global singleton in background.js. If a future refactor introduces multiple background script entry points, the queue state will need to be shared accordingly. The 15 s message timeout and 3 s readiness timeout are conservative defaults and can be tuned based on observed performance.

@timerring timerring self-assigned this Feb 21, 2026
@timerring timerring added the documentation Improvements or additions to documentation label Feb 21, 2026
Copy link
Member Author

@timerring timerring left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@timerring timerring merged commit e447e11 into main Feb 21, 2026
@timerring timerring deleted the dev branch February 21, 2026 06:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant