From 57470e5a7f363b78d11f007f874036e7338948fc Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Sun, 12 Sep 2021 22:09:29 +0300 Subject: [PATCH] Potential optimization to message deletion loop --- backend/src/data/cleanup/messages.ts | 66 +++++++++++++++++++--------- 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/backend/src/data/cleanup/messages.ts b/backend/src/data/cleanup/messages.ts index 0a5d038b..3dd094ff 100644 --- a/backend/src/data/cleanup/messages.ts +++ b/backend/src/data/cleanup/messages.ts @@ -11,7 +11,7 @@ import { SavedMessage } from "../entities/SavedMessage"; const RETENTION_PERIOD = 1 * DAYS; const BOT_MESSAGE_RETENTION_PERIOD = 30 * MINUTES; const DELETED_MESSAGE_RETENTION_PERIOD = 5 * MINUTES; -const CLEAN_PER_LOOP = 500; +const CLEAN_PER_LOOP = 200; export async function cleanupMessages(): Promise { let cleaned = 0; @@ -25,38 +25,64 @@ export async function cleanupMessages(): Promise { // SELECT + DELETE messages in batches // This is to avoid deadlocks that happened frequently when deleting with the same criteria as the select below // when a message was being inserted at the same time - let rows; + let ids: string[]; do { - rows = await connection.query( + const deletedMessageRows = await connection.query( ` SELECT id FROM messages WHERE ( - deleted_at IS NOT NULL - AND deleted_at <= ? - ) - OR ( - posted_at <= ? - AND is_permanent = 0 - ) - OR ( - is_bot = 1 - AND posted_at <= ? - AND is_permanent = 0 - ) + deleted_at IS NOT NULL + AND deleted_at <= ? + ) LIMIT ${CLEAN_PER_LOOP} `, - [deletedAtThreshold, postedAtThreshold, botPostedAtThreshold], + [deletedAtThreshold], ); - if (rows.length > 0) { + const oldPostedRows = await connection.query( + ` + SELECT id + FROM messages + WHERE ( + posted_at <= ? + AND is_permanent = 0 + ) + LIMIT ${CLEAN_PER_LOOP} + `, + [postedAtThreshold], + ); + + const oldBotPostedRows = await connection.query( + ` + SELECT id + FROM messages + WHERE ( + is_bot = 1 + AND posted_at <= ? + AND is_permanent = 0 + ) + LIMIT ${CLEAN_PER_LOOP} + `, + [botPostedAtThreshold], + ); + + ids = Array.from( + new Set([ + ...deletedMessageRows.map((r) => r.id), + ...oldPostedRows.map((r) => r.id), + ...oldBotPostedRows.map((r) => r.id), + ]), + ); + + if (ids.length > 0) { await messagesRepository.delete({ - id: In(rows.map((r) => r.id)), + id: In(ids), }); } - cleaned += rows.length; - } while (rows.length === CLEAN_PER_LOOP); + cleaned += ids.length; + } while (ids.length > 0); return cleaned; }