Batch and de-duplicate profile key updates

This commit is contained in:
Fedor Indutny 2021-05-11 11:26:44 -07:00 committed by GitHub
parent c2a0072fa1
commit e51260a23f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 31 deletions

View file

@ -2675,6 +2675,30 @@ export async function startApp(): Promise<void> {
return confirm();
}
const respondWithProfileKeyBatcher = createBatcher<ConversationModel>({
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<void> {
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(

View file

@ -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<boolean> {
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;
}