From 7d72001bb94a91bfc895b98b6ec325fe2b1f5e58 Mon Sep 17 00:00:00 2001 From: Tio Date: Sat, 14 Mar 2026 07:03:44 -0400 Subject: [PATCH] Address review: identity-check on removeActiveClient Use removeActiveClientIfMatch to only deregister the active client if it matches the instance owned by the stopping monitor. Prevents a reconnect race where the first monitor's stop() would deregister the second monitor's healthy client. Co-Authored-By: Claude Opus 4.6 (1M context) --- extensions/irc/src/active-clients.ts | 11 +++++++++++ extensions/irc/src/monitor.ts | 6 ++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/extensions/irc/src/active-clients.ts b/extensions/irc/src/active-clients.ts index 47ac90c747f..cd960e201be 100644 --- a/extensions/irc/src/active-clients.ts +++ b/extensions/irc/src/active-clients.ts @@ -22,3 +22,14 @@ export function getActiveClient(accountId: string): IrcClient | undefined { export function removeActiveClient(accountId: string): void { activeClients.delete(accountId); } + +/** + * Only remove the active client if it matches the expected instance. + * Prevents a stopping monitor from deregistering a newer monitor's + * healthy client during reconnect races. + */ +export function removeActiveClientIfMatch(accountId: string, expected: IrcClient): void { + if (activeClients.get(accountId) === expected) { + activeClients.delete(accountId); + } +} diff --git a/extensions/irc/src/monitor.ts b/extensions/irc/src/monitor.ts index 8ba5fd95338..6eb487f586f 100644 --- a/extensions/irc/src/monitor.ts +++ b/extensions/irc/src/monitor.ts @@ -1,6 +1,6 @@ import { resolveLoggerBackedRuntime } from "openclaw/plugin-sdk/extension-shared"; import { resolveIrcAccount } from "./accounts.js"; -import { setActiveClient, removeActiveClient } from "./active-clients.js"; +import { setActiveClient, removeActiveClientIfMatch } from "./active-clients.js"; import { connectIrcClient, type IrcClient } from "./client.js"; import { buildIrcConnectOptions } from "./connect-options.js"; import { handleIrcInbound } from "./inbound.js"; @@ -141,7 +141,9 @@ export async function monitorIrcProvider(opts: IrcMonitorOptions): Promise<{ sto return { stop: () => { - removeActiveClient(account.accountId); + if (client) { + removeActiveClientIfMatch(account.accountId, client); + } client?.quit("shutdown"); client = null; },