Throttle chat backups (#2865)

* Throttle chat backups

* Throttle chat backups and apply backup interval throttling

- Added a new configuration option `chatBackupThrottleInterval` to the `config.yaml` file to specify the interval in milliseconds to throttle chat backups per user.
- Updated the `getBackupFunction` function in `chats.js` to use the `chatBackupThrottleInterval` value from the configuration file when creating a throttled backup function.
This commit is contained in:
Cohee 2024-09-17 18:18:35 +03:00 committed by GitHub
parent 15f7d9407a
commit 1366c2741d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 26 additions and 2 deletions

View File

@ -83,6 +83,8 @@ skipContentCheck: false
disableChatBackup: false
# Number of backups to keep for each chat and settings file
numberOfBackups: 50
# Interval in milliseconds to throttle chat backups per user
chatBackupThrottleInterval: 10000
# Allowed hosts for card downloads
whitelistImportDomains:
- localhost

View File

@ -4,6 +4,7 @@ const readline = require('readline');
const express = require('express');
const sanitize = require('sanitize-filename');
const writeFileAtomicSync = require('write-file-atomic').sync;
const _ = require('lodash');
const { jsonParser, urlencodedParser } = require('../express-common');
const { getConfigValue, humanizedISO8601DateTime, tryParse, generateTimestamp, removeOldBackups } = require('../util');
@ -34,6 +35,27 @@ function backupChat(directory, name, chat) {
}
}
const backupFunctions = new Map();
/**
* Gets a backup function for a user.
* @param {string} handle User handle
* @returns {function(string, string, string): void} Backup function
*/
function getBackupFunction(handle) {
const throttleInterval = getConfigValue('chatBackupThrottleInterval', 10_000);
if (!backupFunctions.has(handle)) {
backupFunctions.set(handle, _.throttle(backupChat, throttleInterval, { leading: true, trailing: true }));
}
return backupFunctions.get(handle);
}
process.on('exit', () => {
for (const func of backupFunctions.values()) {
func.flush();
}
});
/**
* Imports a chat from Ooba's format.
* @param {string} userName User name
@ -147,7 +169,7 @@ router.post('/save', jsonParser, function (request, response) {
const fileName = `${String(request.body.file_name)}.jsonl`;
const filePath = path.join(request.user.directories.chats, directoryName, sanitize(fileName));
writeFileAtomicSync(filePath, jsonlData, 'utf8');
backupChat(request.user.directories.backups, directoryName, jsonlData);
getBackupFunction(request.user.profile.handle)(request.user.directories.backups, directoryName, jsonlData);
return response.send({ result: 'ok' });
} catch (error) {
response.send(error);
@ -446,7 +468,7 @@ router.post('/group/save', jsonParser, (request, response) => {
let chat_data = request.body.chat;
let jsonlData = chat_data.map(JSON.stringify).join('\n');
writeFileAtomicSync(pathToFile, jsonlData, 'utf8');
backupChat(request.user.directories.backups, String(id), jsonlData);
getBackupFunction(request.user.profile.handle)(request.user.directories.backups, String(id), jsonlData);
return response.send({ ok: true });
});