From a5b7ce7ef96c88e40aa8dbc55360c05e4718a18e Mon Sep 17 00:00:00 2001 From: Renato Alcara Date: Sun, 26 Apr 2026 13:21:52 -0300 Subject: [PATCH] perf(inbound): detach post-upsert work from buffered function Removes the await around Promise.all([doAppStateSync, processMessage]) inside upsertMessage. createBufferedFunction (event-buffer.ts:819) only schedules the buffer flush AFTER its work() callback resolves, so awaiting post-upsert work pinned the messages.upsert emit inside the buffer for the full duration of processMessage (signal cleanup, store writes, tcToken maintenance, history mappings). After this change the buffered function returns as soon as the synchronous state-machine bookkeeping completes, the debounced flush releases messages.upsert to the consumer, and processMessage / doAppStateSync run in the background. Failures are caught and warn-logged so unhandled rejections cannot crash the socket. This is the last remaining sync hop on the inbound hot path that was still adding latency on top of PR #390 (fire-and-forget LID mapping + tcToken history sync). --- src/Socket/chats.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 2b3bf86a..3d1152e7 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -1411,7 +1411,13 @@ export const makeChatsSocket = (config: SocketConfig) => { } } - await Promise.all([ + // Fire-and-forget: post-upsert work (history app-state sync + processMessage) + // must NOT block the buffered function. Awaiting here keeps `messages.upsert` + // pinned in the event buffer (createBufferedFunction only schedules flush + // after work() resolves), delaying delivery to the consumer by the duration + // of processMessage. Detaching this work releases the emit on the next debounce + // tick while signal/store/tcToken side-effects continue in the background. + Promise.all([ (async () => { if (shouldProcessHistoryMsg) { await doAppStateSync() @@ -1428,7 +1434,7 @@ export const makeChatsSocket = (config: SocketConfig) => { options: config.options, getMessage }) - ]) + ]).catch(err => logger?.warn({ err }, 'background post-upsert work failed')) // If the app state key arrives and we are waiting to sync, trigger the sync now. if (msg.message?.protocolMessage?.appStateSyncKeyShare && syncState === SyncState.Syncing) {