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.

1366c2741d35aaaa4680425b8c8775c381edfba4

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
2 files changed, +26 -2Showing whitespace changes
default/config.yaml+2 -0
@@ -83,6 +83,8 @@ skipContentCheck: false
83disableChatBackup: false83disableChatBackup: false
84# Number of backups to keep for each chat and settings file84# Number of backups to keep for each chat and settings file
85numberOfBackups: 5085numberOfBackups: 50
86# Interval in milliseconds to throttle chat backups per user
87chatBackupThrottleInterval: 10000
86# Allowed hosts for card downloads88# Allowed hosts for card downloads
87whitelistImportDomains:89whitelistImportDomains:
88 - localhost90 - localhost
src/endpoints/chats.js+24 -2
@@ -4,6 +4,7 @@ const readline = require('readline');
4const express = require('express');4const express = require('express');
5const sanitize = require('sanitize-filename');5const sanitize = require('sanitize-filename');
6const writeFileAtomicSync = require('write-file-atomic').sync;6const writeFileAtomicSync = require('write-file-atomic').sync;
7const _ = require('lodash');
78
8const { jsonParser, urlencodedParser } = require('../express-common');9const { jsonParser, urlencodedParser } = require('../express-common');
9const { getConfigValue, humanizedISO8601DateTime, tryParse, generateTimestamp, removeOldBackups } = require('../util');10const { getConfigValue, humanizedISO8601DateTime, tryParse, generateTimestamp, removeOldBackups } = require('../util');
@@ -34,6 +35,27 @@ function backupChat(directory, name, chat) {
34 }35 }
35}36}
3637
38const backupFunctions = new Map();
39
40/**
41 * Gets a backup function for a user.
42 * @param {string} handle User handle
43 * @returns {function(string, string, string): void} Backup function
44 */
45function getBackupFunction(handle) {
46 const throttleInterval = getConfigValue('chatBackupThrottleInterval', 10_000);
47 if (!backupFunctions.has(handle)) {
48 backupFunctions.set(handle, _.throttle(backupChat, throttleInterval, { leading: true, trailing: true }));
49 }
50 return backupFunctions.get(handle);
51}
52
53process.on('exit', () => {
54 for (const func of backupFunctions.values()) {
55 func.flush();
56 }
57});
58
37/**59/**
38 * Imports a chat from Ooba's format.60 * Imports a chat from Ooba's format.
39 * @param {string} userName User name61 * @param {string} userName User name
@@ -147,7 +169,7 @@ router.post('/save', jsonParser, function (request, response) {
147 const fileName = `${String(request.body.file_name)}.jsonl`;169 const fileName = `${String(request.body.file_name)}.jsonl`;
148 const filePath = path.join(request.user.directories.chats, directoryName, sanitize(fileName));170 const filePath = path.join(request.user.directories.chats, directoryName, sanitize(fileName));
149 writeFileAtomicSync(filePath, jsonlData, 'utf8');171 writeFileAtomicSync(filePath, jsonlData, 'utf8');
150 backupChat(request.user.directories.backups, directoryName, jsonlData);172 getBackupFunction(request.user.profile.handle)(request.user.directories.backups, directoryName, jsonlData);
151 return response.send({ result: 'ok' });173 return response.send({ result: 'ok' });
152 } catch (error) {174 } catch (error) {
153 response.send(error);175 response.send(error);
@@ -446,7 +468,7 @@ router.post('/group/save', jsonParser, (request, response) => {
446 let chat_data = request.body.chat;468 let chat_data = request.body.chat;
447 let jsonlData = chat_data.map(JSON.stringify).join('\n');469 let jsonlData = chat_data.map(JSON.stringify).join('\n');
448 writeFileAtomicSync(pathToFile, jsonlData, 'utf8');470 writeFileAtomicSync(pathToFile, jsonlData, 'utf8');
449 backupChat(request.user.directories.backups, String(id), jsonlData);471 getBackupFunction(request.user.profile.handle)(request.user.directories.backups, String(id), jsonlData);
450 return response.send({ ok: true });472 return response.send({ ok: true });
451});473});
452474