mirror of https://github.com/openclaw/openclaw.git
fix: force-stop lingering gateway client sockets
This commit is contained in:
parent
4dbab064f0
commit
727fc79ed2
|
|
@ -23,6 +23,8 @@ class MockWebSocket {
|
|||
private closeHandlers: WsEventHandlers["close"][] = [];
|
||||
private errorHandlers: WsEventHandlers["error"][] = [];
|
||||
readonly sent: string[] = [];
|
||||
closeCalls = 0;
|
||||
terminateCalls = 0;
|
||||
|
||||
constructor(_url: string, _options?: unknown) {
|
||||
wsInstances.push(this);
|
||||
|
|
@ -52,9 +54,14 @@ class MockWebSocket {
|
|||
}
|
||||
|
||||
close(code?: number, reason?: string): void {
|
||||
this.closeCalls += 1;
|
||||
this.emitClose(code ?? 1000, reason ?? "");
|
||||
}
|
||||
|
||||
terminate(): void {
|
||||
this.terminateCalls += 1;
|
||||
}
|
||||
|
||||
send(data: string): void {
|
||||
this.sent.push(data);
|
||||
}
|
||||
|
|
@ -297,6 +304,29 @@ describe("GatewayClient close handling", () => {
|
|||
client.stop();
|
||||
});
|
||||
|
||||
it("force-terminates a lingering socket after stop", async () => {
|
||||
vi.useFakeTimers();
|
||||
try {
|
||||
const client = new GatewayClient({
|
||||
url: "ws://127.0.0.1:18789",
|
||||
});
|
||||
|
||||
client.start();
|
||||
const ws = getLatestWs();
|
||||
|
||||
client.stop();
|
||||
|
||||
expect(ws.closeCalls).toBe(1);
|
||||
expect(ws.terminateCalls).toBe(0);
|
||||
|
||||
await vi.advanceTimersByTimeAsync(250);
|
||||
|
||||
expect(ws.terminateCalls).toBe(1);
|
||||
} finally {
|
||||
vi.useRealTimers();
|
||||
}
|
||||
});
|
||||
|
||||
it("does not clear persisted device auth when explicit shared token is provided", () => {
|
||||
const onClose = vi.fn();
|
||||
const identity: DeviceIdentity = {
|
||||
|
|
|
|||
|
|
@ -117,6 +117,8 @@ export function describeGatewayCloseCode(code: number): string | undefined {
|
|||
return GATEWAY_CLOSE_CODE_HINTS[code];
|
||||
}
|
||||
|
||||
const FORCE_STOP_TERMINATE_GRACE_MS = 250;
|
||||
|
||||
export class GatewayClient {
|
||||
private ws: WebSocket | null = null;
|
||||
private opts: GatewayClientOptions;
|
||||
|
|
@ -273,8 +275,17 @@ export class GatewayClient {
|
|||
clearInterval(this.tickTimer);
|
||||
this.tickTimer = null;
|
||||
}
|
||||
this.ws?.close();
|
||||
const ws = this.ws;
|
||||
this.ws = null;
|
||||
if (ws) {
|
||||
ws.close();
|
||||
const forceTerminateTimer = setTimeout(() => {
|
||||
try {
|
||||
ws.terminate();
|
||||
} catch {}
|
||||
}, FORCE_STOP_TERMINATE_GRACE_MS);
|
||||
forceTerminateTimer.unref?.();
|
||||
}
|
||||
this.flushPendingErrors(new Error("gateway client stopped"));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue