diff --git a/ts/background.ts b/ts/background.ts index 9a775de8c..f2d04f25f 100644 --- a/ts/background.ts +++ b/ts/background.ts @@ -2675,6 +2675,30 @@ export async function startApp(): Promise { return confirm(); } + const respondWithProfileKeyBatcher = createBatcher({ + name: 'respondWithProfileKeyBatcher', + processBatch(batch) { + const deduped = new Set(batch); + deduped.forEach(async sender => { + try { + if (!(await shouldRespondWithProfileKey(sender))) { + return; + } + } catch (error) { + window.log.error( + 'respondWithProfileKeyBatcher error', + error && error.stack + ); + } + + sender.queueJob(() => sender.sendProfileKeyUpdate()); + }); + }, + + wait: 200, + maxSize: Infinity, + }); + // Note: We do very little in this function, since everything in handleDataMessage is // inside a conversation-specific queue(). Any code here might run before an earlier // message is processed in handleDataMessage(). @@ -2701,23 +2725,17 @@ export async function startApp(): Promise { const message = initIncomingMessage(data, messageDescriptor); - // We don't need this to interrupt our processing of the message, so we "fire and - // forget". - (async () => { - if (await shouldRespondWithProfileKey(message)) { - const contact = message.getContact(); - if (!contact) { - assert(false, 'Expected message to have a contact'); - return; - } + if (message.isIncoming() && message.get('unidentifiedDeliveryReceived')) { + const sender = message.getContact(); - profileKeyResponseQueue.add(() => { - contact.queueJob(() => contact.sendProfileKeyUpdate()); - }); + if (!sender) { + throw new Error('MessageModel has no sender.'); } - })().catch(err => { - window.log.error(err); - }); + + profileKeyResponseQueue.add(() => { + respondWithProfileKeyBatcher.add(sender); + }); + } if (data.message.reaction) { window.normalizeUuids( diff --git a/ts/util/shouldRespondWithProfileKey.ts b/ts/util/shouldRespondWithProfileKey.ts index 118a6c21d..136f7c236 100644 --- a/ts/util/shouldRespondWithProfileKey.ts +++ b/ts/util/shouldRespondWithProfileKey.ts @@ -1,25 +1,11 @@ // Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import { MessageModel } from '../models/messages'; -import { assert } from './assert'; +import { ConversationModel } from '../models/conversations'; export async function shouldRespondWithProfileKey( - message: MessageModel + sender: ConversationModel ): Promise { - if (!message.isIncoming() || message.get('unidentifiedDeliveryReceived')) { - return false; - } - - const sender = message.getContact(); - if (!sender) { - assert( - false, - 'MessageModel#shouldRespondWithProfileKey had no sender. Returning false' - ); - return false; - } - if (sender.isMe() || !sender.getAccepted() || sender.isBlocked()) { return false; }