Deduplicate conversations before passing to redux

Receiving a single message on conversations triggers ~4 updates.
However, since `.format()` is called on next tick - the value is going
to be the same regardless of which particular update triggered it. Batch
conversations and de-duplicate them before passing to redux to save
time.
This commit is contained in:
Fedor Indutny 2021-04-07 17:35:22 -07:00 committed by Josh Perez
parent 4fd3ed7242
commit 6ff55914f0

View file

@ -12,6 +12,8 @@ import { SenderCertificateMode } from './metadata/SecretSessionCipher';
import { routineProfileRefresh } from './routineProfileRefresh';
import { isMoreRecentThan, isOlderThan } from './util/timestamp';
import { isValidReactionEmoji } from './reactions/isValidReactionEmoji';
import { ConversationModel } from './models/conversations';
import { createBatcher } from './util/batcher';
const MAX_ATTACHMENT_DOWNLOAD_AGE = 3600 * 72 * 1000;
@ -849,19 +851,35 @@ export async function startApp(): Promise<void> {
}
conversationAdded(conversation.id, conversation.format());
});
convoCollection.on('change', conversation => {
if (!conversation) {
return;
}
const changedConvoBatcher = createBatcher<ConversationModel>({
name: 'changedConvoBatcher',
processBatch(batch) {
const deduped = Array.from(new Set(batch));
window.log.info(
'changedConvoBatcher: deduped ' +
`${batch.length} into ${deduped.length}`
);
deduped.forEach(conversation => {
conversationChanged(conversation.id, conversation.format());
});
},
// This delay ensures that the .format() call isn't synchronous as a
// Backbone property is changed. Important because our _byUuid/_byE164
// lookups aren't up-to-date as the change happens; just a little bit
// after.
setTimeout(
() => conversationChanged(conversation.id, conversation.format()),
1
);
wait: 1,
maxSize: Infinity,
});
convoCollection.on('change', conversation => {
if (!conversation) {
return;
}
changedConvoBatcher.add(conversation);
});
convoCollection.on('reset', removeAllConversations);