Skip to content

fix(browser): flush pending extension timers on relay stop#24142

Closed
kevinWangSheng wants to merge 3 commits intoopenclaw:mainfrom
kevinWangSheng:fix/extension-relay-stop-cleanup
Closed

fix(browser): flush pending extension timers on relay stop#24142
kevinWangSheng wants to merge 3 commits intoopenclaw:mainfrom
kevinWangSheng:fix/extension-relay-stop-cleanup

Conversation

@kevinWangSheng
Copy link

@kevinWangSheng kevinWangSheng commented Feb 23, 2026

Summary

  • Problem: The stop() method in extension-relay.ts closes WebSocket connections and the HTTP server but does not explicitly clean up pendingExtension Map entries and their associated timers.
  • Why it matters: If extensionWs?.close() triggers the close event asynchronously after server.close() has already completed, timer callbacks could fire against torn-down state, leading to potential errors or undefined behavior.
  • What changed: Added cleanup of all pending extension request timers (clearTimeout + reject + clear) in the stop() method, before closing connections and the server.
  • What did NOT change (scope boundary): No other files or logic paths were modified. The existing WebSocket close handler cleanup remains unchanged.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • N/A

User-visible / Behavior Changes

None

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: Any
  • Runtime/container: Node 22+
  • Model/provider: N/A
  • Integration/channel (if any): Chrome extension relay (browser CDP)

Steps

  1. Start the extension relay server with active pending extension requests
  2. Call stop() on the relay server
  3. Observe that pending timers are now cleaned up before server shutdown

Expected

  • All pending extension request timers are cleared and their promises rejected with "server stopping" before the server closes

Actual

  • Previously, timers were only cleaned up via the WebSocket close event handler, which may fire asynchronously after server teardown

Evidence

  • Trace/log snippets: Code inspection confirms the cleanup pattern matches the existing WebSocket close handler (lines 649-653)

Human Verification (required)

  • Verified scenarios: Code review confirms the cleanup logic matches the existing pattern in the WebSocket close handler
  • Edge cases checked: Empty pendingExtension map (no-op), multiple pending requests
  • What you did not verify: Live end-to-end testing with a real Chrome extension connection

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: Revert the commit (remove 4 added lines in stop())
  • Files/config to restore: src/browser/extension-relay.ts
  • Known bad symptoms reviewers should watch for: Unexpected "server stopping" rejection errors if stop() is called while requests are in flight

Risks and Mitigations

  • Risk: Pending request callers receive "server stopping" rejection instead of a timeout
    • Mitigation: This is the correct behavior - callers should handle rejection during shutdown, and it's better than timer callbacks firing against torn-down state

🤖 Generated with Claude Code

Greptile Summary

Fixed a race condition in the extension relay server shutdown sequence by adding explicit cleanup of pending extension request timers before closing connections. The cleanup pattern matches the existing WebSocket close handler (lines 653-657) and prevents timer callbacks from firing against torn-down state.

  • Added synchronous timer cleanup (clearTimeout + reject + clear) in the stop() method before closing WebSocket connections
  • Ensures pending request promises are rejected with "server stopping" error rather than timing out after shutdown
  • No changes to existing WebSocket close handler cleanup logic

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The change is a focused bug fix that adds proper cleanup logic to prevent a race condition during server shutdown. The implementation exactly mirrors the existing cleanup pattern in the WebSocket close handler (lines 653-657), ensuring consistency. The cleanup is done synchronously before closing connections, which is the correct order. Edge cases (empty map, duplicate cleanup from close handler) are handled correctly.
  • No files require special attention

Last reviewed commit: c0f68ec

The stop() method closes WebSocket connections and the HTTP server but
does not explicitly clean up pendingExtension Map entries and their
associated timers. If extensionWs?.close() triggers the close event
asynchronously after server.close() has already completed, timer
callbacks could fire against torn-down state.

Flush all pending extension request timers before closing connections,
matching the cleanup pattern already used in the WebSocket close handler.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The yieldMs: 10 parameter causes a race condition on Windows CI where
the exec result status is still 'running' instead of 'completed'.
Upstream PR openclaw#24070 identified this as a known flaky test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@openclaw-barnacle openclaw-barnacle bot added the agents Agent runtime and tooling label Feb 23, 2026
@openclaw-barnacle openclaw-barnacle bot removed the agents Agent runtime and tooling label Feb 24, 2026
steipete added a commit that referenced this pull request Feb 26, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR #24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
@steipete
Copy link
Contributor

Landed on main via ce833cd6d.

What I landed from this PR:

SHA mapping:

  • original fix commit: c0f68ec3ea811886481ca31e5fc479bd8d8d9803
  • landed commit: ce833cd6d

Thanks for the fix, @kevinWangSheng.

@steipete steipete closed this Feb 26, 2026
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Feb 27, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Feb 27, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
(cherry picked from commit 19e722f)
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Feb 27, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
(cherry picked from commit 19e722f)
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Feb 27, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
(cherry picked from commit 19e722f)
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Feb 27, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
(cherry picked from commit 19e722f)
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Feb 27, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
(cherry picked from commit 19e722f)
execute008 pushed a commit to execute008/openclaw that referenced this pull request Feb 27, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
r4jiv007 pushed a commit to r4jiv007/openclaw that referenced this pull request Feb 28, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
mylukin pushed a commit to mylukin/openclaw that referenced this pull request Feb 28, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Feb 28, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
(cherry picked from commit 19e722f)
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Feb 28, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
(cherry picked from commit 19e722f)
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Feb 28, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
(cherry picked from commit 19e722f)
wanjizheng pushed a commit to wanjizheng/openclaw that referenced this pull request Feb 28, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
(cherry picked from commit 19e722f)
vincentkoc pushed a commit to Sid-Qin/openclaw that referenced this pull request Feb 28, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
vincentkoc pushed a commit to rylena/rylen-openclaw that referenced this pull request Feb 28, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
steipete added a commit to Sid-Qin/openclaw that referenced this pull request Mar 2, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
robertchang-ga pushed a commit to robertchang-ga/openclaw that referenced this pull request Mar 2, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
dorgonman pushed a commit to kanohorizonia/openclaw that referenced this pull request Mar 3, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
thebenjaminlee pushed a commit to escape-velocity-ventures/openclaw that referenced this pull request Mar 7, 2026
Flush pending extension request timers/rejections during relay shutdown and document in changelog.
Landed from contributor @kevinWangSheng (PR openclaw#24142).

Co-authored-by: Shawn <118158941+kevinWangSheng@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants