fix: skip recent deleted message empty react changes

This commit is contained in:
Audric Ackermann 2022-10-07 15:35:09 +11:00
parent 0cc7994c12
commit ad03fbd497
3 changed files with 88 additions and 33 deletions

View file

@ -36,6 +36,7 @@ import { createSwarmMessageSentFromUs } from '../../../../models/messageFactory'
import { Data } from '../../../../data/data';
import { processMessagesUsingCache } from './sogsV3MutationCache';
import { destroyMessagesAndUpdateRedux } from '../../../../util/expiringMessages';
import { sogsRollingDeletions } from './sogsRollingDeletions';
/**
* Get the convo matching those criteria and make sure it is an opengroup convo, or return null.
@ -155,29 +156,28 @@ async function filterOutMessagesInvalidSignature(
return signaturesValidMessages;
}
let totalDeletedMessages = 0;
const handleSogsV3DeletedMessages = async (
messages: Array<OpenGroupMessageV4>,
serverUrl: string,
roomId: string
) => {
const deletions = messages.filter(m => Boolean(m.deleted));
const exceptDeletion = messages.filter(m => !m.deleted);
if (!deletions.length) {
return messages;
const messagesDeleted = messages.filter(m => Boolean(m.deleted));
const messagesWithoutDeleted = messages.filter(m => !m.deleted);
if (!messagesDeleted.length) {
return messagesWithoutDeleted;
}
totalDeletedMessages += deletions.length;
console.warn(
JSON.stringify({
totalDeletedMessages,
})
);
const allIdsRemoved = deletions.map(m => m.id);
const allIdsRemoved = messagesDeleted.map(m => m.id);
try {
const convoId = getOpenGroupV2ConversationId(serverUrl, roomId);
const convo = getConversationController().get(convoId);
const messageIds = await Data.getMessageIdsFromServerIds(allIdsRemoved, convo.id);
allIdsRemoved.forEach(removedId => {
sogsRollingDeletions.addMessageDeletedId(convoId, removedId);
});
if (messageIds && messageIds.length) {
await destroyMessagesAndUpdateRedux(
messageIds.map(messageId => ({
@ -189,14 +189,9 @@ const handleSogsV3DeletedMessages = async (
} catch (e) {
window?.log?.warn('handleDeletions failed:', e);
}
return exceptDeletion;
return messagesWithoutDeleted;
};
// tslint:disable-next-line: one-variable-per-declaration
let totalEmptyReactions = 0,
totalMessagesWithResolvedBlindedIdsIfFound = 0,
totalMessageReactions = 0;
// tslint:disable-next-line: max-func-body-length cyclomatic-complexity
const handleMessagesResponseV4 = async (
messages: Array<OpenGroupMessageV4>,
@ -296,8 +291,6 @@ const handleMessagesResponseV4 = async (
const incomingMessageSeqNo = compact(messages.map(n => n.seqno));
const maxNewMessageSeqNo = Math.max(...incomingMessageSeqNo);
totalMessagesWithResolvedBlindedIdsIfFound += messagesWithResolvedBlindedIdsIfFound.length;
for (let index = 0; index < messagesWithResolvedBlindedIdsIfFound.length; index++) {
const msgToHandle = messagesWithResolvedBlindedIdsIfFound[index];
try {
@ -323,25 +316,24 @@ const handleMessagesResponseV4 = async (
await OpenGroupData.saveV2OpenGroupRoom(roomInfosRefreshed);
const messagesWithReactions = messages.filter(m => m.reactions !== undefined);
const messagesWithEmptyReactions = messagesWithReactions.filter(m => isEmpty(m.reactions));
totalMessageReactions += messagesWithReactions.length;
totalEmptyReactions += messagesWithEmptyReactions.length;
console.warn(
JSON.stringify({
totalMessagesWithResolvedBlindedIdsIfFound,
totalMessageReactions,
totalEmptyReactions,
})
);
if (messagesWithReactions.length > 0) {
const conversationId = getOpenGroupV2ConversationId(serverUrl, roomId);
const groupConvo = getConversationController().get(conversationId);
if (groupConvo && groupConvo.isOpenGroupV2()) {
for (const message of messagesWithReactions) {
for (const messageWithReaction of messagesWithReactions) {
if (isEmpty(messageWithReaction.reactions)) {
/*
* When a message is deleted from the server, we get the deleted event as a data: null on the message itself
* and an update on its reactions.
* But, because we just deleted that message, we can skip trying to udpate its reactions: it's not in the DB anymore.
*/
if (sogsRollingDeletions.hasMessageDeletedId(conversationId, messageWithReaction.id)) {
continue;
}
}
void groupConvo.queueJob(async () => {
await processMessagesUsingCache(serverUrl, roomId, message);
await processMessagesUsingCache(serverUrl, roomId, messageWithReaction);
});
}
}

View file

@ -0,0 +1,32 @@
import { RingBuffer } from '../../../utils/RingBuffer';
const rollingDeletedMessageIds: Map<string, RingBuffer<number>> = new Map();
// keep 2000 deleted message ids in memory
const perRoomRollingRemovedIds = 2000;
const addMessageDeletedId = (conversationId: string, messageDeletedId: number) => {
if (!rollingDeletedMessageIds.has(conversationId)) {
rollingDeletedMessageIds.set(conversationId, new RingBuffer<number>(perRoomRollingRemovedIds));
}
const ringBuffer = rollingDeletedMessageIds.get(conversationId);
if (!ringBuffer) {
return;
}
ringBuffer.add(messageDeletedId);
};
const hasMessageDeletedId = (conversationId: string, messageDeletedId: number) => {
if (!rollingDeletedMessageIds.has(conversationId)) {
return false;
}
const messageIdWasDeletedRecently = rollingDeletedMessageIds
?.get(conversationId)
?.has(messageDeletedId);
return messageIdWasDeletedRecently;
};
export const sogsRollingDeletions = { addMessageDeletedId, hasMessageDeletedId };

View file

@ -0,0 +1,31 @@
export class RingBuffer<T> {
private buffer: Array<T> = [];
private readonly capacity: number;
constructor(capacity: number) {
this.capacity = capacity;
}
public getCapacity(): number {
return this.capacity;
}
public add(item: T) {
this.buffer.push(item);
this.crop();
}
public has(item: T) {
return this.buffer.includes(item);
}
public clear() {
this.buffer = [];
}
private crop() {
while (this.buffer.length > this.capacity) {
this.buffer.shift();
}
}
}