perf(reconnect): eliminate race condition between connection:open and offline message delivery

perf(reconnect): eliminate race condition between connection:open and offline message delivery
This commit is contained in:
Renato Alcara
2026-02-26 18:54:19 -03:00
committed by GitHub
parent 8cdea36b98
commit 9c1adfd05f
2 changed files with 24 additions and 16 deletions
+23 -14
View File
@@ -1499,27 +1499,36 @@ export const makeSocket = (config: SocketConfig) => {
})
// login complete
ws.on('CB:success', async (node: BinaryNode) => {
try {
await uploadPreKeysToServerIfRequired()
await sendPassiveIq('active')
// After successful login, validate our key-bundle against server
try {
await digestKeyBundle()
} catch (e) {
logger.warn({ e }, 'failed to run digest after login')
}
} catch (err) {
logger.warn({ err }, 'failed to send initial passive iq')
}
logger.info('opened connection to WA')
clearTimeout(qrTimer) // will never happen in all likelyhood -- but just in case WA sends success on first try
ev.emit('creds.update', { me: { ...authState.creds.me!, lid: node.attrs.lid } })
// Emit connection:open immediately so the application layer begins processing
// incoming messages without waiting for any WA round-trips.
ev.emit('connection.update', { connection: 'open' })
// ─── Background: sendPassiveIq + pre-key validation + key-bundle digest ──
// sendPassiveIq('active') tells the WA edge server to start routing live
// messages to this connection. All three operations involve WA round-trips
// (100500 ms each) but none need to complete before the app can handle
// messages. Run them in parallel, fire-and-forget, non-blocking.
Promise.allSettled([sendPassiveIq('active'), uploadPreKeysToServerIfRequired(), digestKeyBundle()])
.then(results => {
const [passiveResult] = results
if (passiveResult.status === 'rejected') {
logger.warn({ err: passiveResult.reason }, 'failed to send initial passive iq')
}
for (const result of results.slice(1)) {
if (result.status === 'rejected') {
logger.warn({ err: result.reason }, 'background key operation failed after login (non-critical)')
}
}
})
.catch(err => {
logger.error({ err }, 'unexpected error in background post-login handler')
})
// Record successful connection metrics
recordConnectionAttempt('success')
incrementActiveConnections()
+1 -2
View File
@@ -1,4 +1,3 @@
import Long from 'long'
import type { Readable } from 'stream'
import type { URL } from 'url'
import { proto } from '../../WAProto/index.js'
@@ -30,7 +29,7 @@ export type WAMessageKey = proto.IMessageKey & {
export type PlaceholderMessageData = {
key: WAMessageKey
pushName?: string | null
messageTimestamp?: number | Long | null
messageTimestamp?: WAMessage['messageTimestamp']
participant?: string | null
participantAlt?: string | null
}