3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-03-18 23:09:59 +00:00
zeppelin/backend/src/data/cleanup/messages.ts

90 lines
2.4 KiB
TypeScript
Raw Normal View History

import moment from "moment-timezone";
2023-07-01 12:17:45 +00:00
import { In } from "typeorm";
import { DAYS, DBDateFormat, MINUTES, SECONDS, sleep } from "../../utils";
2023-07-01 12:17:45 +00:00
import { dataSource } from "../dataSource";
import { SavedMessage } from "../entities/SavedMessage";
/**
* How long message edits, deletions, etc. will include the original message content.
* This is very heavy storage-wise, so keeping it as low as possible is ideal.
*/
const RETENTION_PERIOD = 1 * DAYS;
const BOT_MESSAGE_RETENTION_PERIOD = 30 * MINUTES;
const DELETED_MESSAGE_RETENTION_PERIOD = 5 * MINUTES;
const CLEAN_PER_LOOP = 100;
export async function cleanupMessages(): Promise<number> {
let cleaned = 0;
2023-07-01 12:17:45 +00:00
const messagesRepository = dataSource.getRepository(SavedMessage);
2021-09-11 19:06:51 +03:00
const deletedAtThreshold = moment.utc().subtract(DELETED_MESSAGE_RETENTION_PERIOD, "ms").format(DBDateFormat);
const postedAtThreshold = moment.utc().subtract(RETENTION_PERIOD, "ms").format(DBDateFormat);
const botPostedAtThreshold = moment.utc().subtract(BOT_MESSAGE_RETENTION_PERIOD, "ms").format(DBDateFormat);
// 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 ids: string[];
do {
2023-07-01 12:17:45 +00:00
const deletedMessageRows = await dataSource.query(
`
SELECT id
FROM messages
WHERE (
deleted_at IS NOT NULL
AND deleted_at <= ?
)
LIMIT ${CLEAN_PER_LOOP}
`,
[deletedAtThreshold],
);
2023-07-01 12:17:45 +00:00
const oldPostedRows = await dataSource.query(
`
SELECT id
FROM messages
WHERE (
posted_at <= ?
AND is_permanent = 0
)
LIMIT ${CLEAN_PER_LOOP}
`,
[postedAtThreshold],
);
2023-07-01 12:17:45 +00:00
const oldBotPostedRows = await dataSource.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(ids),
});
await sleep(1 * SECONDS);
}
cleaned += ids.length;
} while (ids.length > 0);
return cleaned;
}