Skip to content

Commit 5416cab

Browse files
steipeteHOYALIM
andcommitted
fix(browser): land PR #21277 dedupe concurrent relay init
Add shared per-port relay initialization dedupe so concurrent callers await a single startup lifecycle, with regression coverage and changelog entry. Landed from contributor @HOYALIM (PR #21277). Co-authored-by: Ho Lim <[email protected]>
1 parent 65d5a91 commit 5416cab

File tree

3 files changed

+560
-527
lines changed

3 files changed

+560
-527
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Docs: https://docs.openclaw.ai
1717
- Browser/Extension relay auth: allow `?token=` query-param auth on relay `/json*` endpoints (consistent with relay WebSocket auth) so curl/devtools-style `/json/version` and `/json/list` probes work without requiring custom headers. Landed from contributor PR #26015 by @Sid-Qin. (#25928)
1818
- Browser/Extension relay shutdown: flush pending extension-request timers/rejections during relay `stop()` before socket/server teardown so in-flight extension waits do not survive shutdown windows. Landed from contributor PR #24142 by @kevinWangSheng.
1919
- Browser/Chrome extension handshake: bind relay WS message handling before `onopen` and add non-blocking `connect.challenge` response handling for gateway-style handshake frames, avoiding stuck `` badge states when challenge frames arrive immediately on connect. Landed from contributor PR #22571 by @pandego. (#22553)
20+
- Browser/Extension relay init: dedupe concurrent same-port relay startup with shared in-flight initialization promises so callers await one startup lifecycle and receive consistent success/failure results. Landed from contributor PR #21277 by @HOYALIM. (Related #20688)
2021
- Auth/Auth profiles: normalize `auth-profiles.json` alias fields (`mode -> type`, `apiKey -> key`) before credential validation so entries copied from `openclaw.json` auth examples are no longer silently dropped. (#26950) thanks @byungsker.
2122
- Cron/Hooks isolated routing: preserve canonical `agent:*` session keys in isolated runs so already-qualified keys are not double-prefixed (for example `agent:main:main` no longer becomes `agent:main:agent:main:main`). Landed from contributor PR #27333 by @MaheshBhushan. (#27289, #27282)
2223
- iOS/Talk mode: stop injecting the voice directive hint into iOS Talk prompts and remove the Voice Directive Hint setting, reducing model bias toward tool-style TTS directives and keeping relay responses text-first by default. (#27543) thanks @ngutman.

src/browser/extension-relay.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,17 @@ describe("chrome extension relay server", () => {
208208
expect(err.message).toContain("401");
209209
});
210210

211+
it("deduplicates concurrent relay starts for the same requested port", async () => {
212+
const port = await getFreePort();
213+
cdpUrl = `http://127.0.0.1:${port}`;
214+
const [first, second] = await Promise.all([
215+
ensureChromeExtensionRelayServer({ cdpUrl }),
216+
ensureChromeExtensionRelayServer({ cdpUrl }),
217+
]);
218+
expect(first).toBe(second);
219+
expect(first.port).toBe(port);
220+
});
221+
211222
it("allows CORS preflight from chrome-extension origins", async () => {
212223
const port = await getFreePort();
213224
cdpUrl = `http://127.0.0.1:${port}`;

0 commit comments

Comments
 (0)