From dc24e60e5b8d4f13f6349ce30894bf57d1b276d1 Mon Sep 17 00:00:00 2001 From: Renato Alcara Date: Sun, 26 Apr 2026 16:03:07 -0300 Subject: [PATCH] fix(inbound): avoid HOL blocking on malformed-JID fallback bucket MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses Copilot review on PR #392. The previous fallback `normalizedChatId || 'unknown'` funneled every message with a missing or malformed chat id into a single global queue on `postUpsertMutex`, head-of-line blocking unrelated malformed inputs behind a shared bucket. Prefer `msg.key?.id` over the constant: it is unique per message so unrelated malformed inputs no longer serialize together, while valid messages continue to hit the normalized chat-id path — preserving the per-chat ordering guarantee where it actually matters. The CodeRabbit concern about `msg.key.id` fragmenting the queue applied to the primary key derivation (where ordering matters); here it is purely a fallback for a corruption edge case where there is no chat to order by anyway. --- src/Socket/chats.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 0a287a63..c2b665b3 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -1486,14 +1486,16 @@ export const makeChatsSocket = (config: SocketConfig) => { // Use getChatId + jidNormalizedUser so the mutex key matches the chat-id // scheme processMessage uses for chat updates (broadcasts target the - // participant). Falling back to a constant bucket avoids fragmenting the - // queue when the key is malformed. - // Compute the normalized value first then apply the fallback: a malformed - // but truthy rawChatId (e.g. missing `@`) makes jidNormalizedUser return - // '', which would otherwise pass through as an empty mutex key. + // participant). When getChatId/jidNormalizedUser yields nothing usable + // (missing or malformed JID), prefer a message-derived fallback over a + // single global 'unknown' bucket — that bucket would head-of-line block + // every malformed message behind a shared queue. msg.key.id is unique + // per message so unrelated malformed inputs no longer serialize together; + // for valid messages we still hit the normalized chat-id path, so the + // per-chat ordering guarantee is unchanged where it matters. const rawChatId = getChatId(msg.key) const normalizedChatId = rawChatId ? jidNormalizedUser(rawChatId) : '' - const postUpsertChatId = normalizedChatId || 'unknown' + const postUpsertChatId = normalizedChatId || msg.key?.id || 'unknown' // Wrap in `postUpsertMutex(chatId)` (a SEPARATE keyed mutex from the outer // `messageMutex` held by the inbound caller) so per-chat ordering of