diff --git a/apps/meteor/app/error-handler/server/lib/RocketChat.ErrorHandler.ts b/apps/meteor/app/error-handler/server/lib/RocketChat.ErrorHandler.ts index 9a4fc28b8f3e9d93c98418476ac3da7c7129afce..0aa8c3a53747edd0c4935b26013b73b2ae9c53bd 100644 --- a/apps/meteor/app/error-handler/server/lib/RocketChat.ErrorHandler.ts +++ b/apps/meteor/app/error-handler/server/lib/RocketChat.ErrorHandler.ts @@ -3,6 +3,11 @@ import { Settings, Users, Rooms } from '@rocket.chat/models'; import { settings } from '../../../settings/server'; import { sendMessage } from '../../../lib/server'; +import { throttledCounter } from '../../../../lib/utils/throttledCounter'; + +const incException = throttledCounter((counter) => { + Settings.incrementValueById('Uncaught_Exceptions_Count', counter).catch(console.error); +}, 10000); class ErrorHandler { reporting: boolean; @@ -40,7 +45,7 @@ class ErrorHandler { async registerHandlers() { process.on('uncaughtException', async (error) => { - await Settings.incrementValueById('Uncaught_Exceptions_Count'); + incException(); if (!this.reporting) { return; } diff --git a/apps/meteor/app/lib/server/lib/meteorFixes.js b/apps/meteor/app/lib/server/lib/meteorFixes.js index 6b88febda2aa99db3ce2e316bc9a3a28f89d422c..39616cac4042b45bfaa41767efb1028d91e2aa3f 100644 --- a/apps/meteor/app/lib/server/lib/meteorFixes.js +++ b/apps/meteor/app/lib/server/lib/meteorFixes.js @@ -1,6 +1,8 @@ import { MongoInternals } from 'meteor/mongo'; import { Settings } from '@rocket.chat/models'; +import { throttledCounter } from '../../../../lib/utils/throttledCounter'; + const timeoutQuery = parseInt(process.env.OBSERVERS_CHECK_TIMEOUT) || 2 * 60 * 1000; const interval = parseInt(process.env.OBSERVERS_CHECK_INTERVAL) || 60 * 1000; const debug = Boolean(process.env.OBSERVERS_CHECK_DEBUG); @@ -44,6 +46,10 @@ setInterval(() => { }); }, interval); +const incException = throttledCounter((counter) => { + Settings.incrementValueById('Uncaught_Exceptions_Count', counter).catch(console.error); +}, 10000); + /** * If some promise is rejected and doesn't have a catch (unhandledRejection) it may cause this finally * here https://github.com/meteor/meteor/blob/be6e529a739f47446950e045f4547ee60e5de7ae/packages/mongo/oplog_tailing.js#L348 @@ -58,8 +64,8 @@ setInterval(() => { * we will start respecting this and exit the process to prevent these kind of problems. */ -process.on('unhandledRejection', async (error) => { - await Settings.incrementValueById('Uncaught_Exceptions_Count'); +process.on('unhandledRejection', (error) => { + incException(); console.error('=== UnHandledPromiseRejection ==='); console.error(error); diff --git a/apps/meteor/ee/server/startup/seatsCap.ts b/apps/meteor/ee/server/startup/seatsCap.ts index 188c8dfe93b91db7429cfceead5019ec7019bff6..d5ec74919568dbc16fa98296d4ddf34719a0ab63 100644 --- a/apps/meteor/ee/server/startup/seatsCap.ts +++ b/apps/meteor/ee/server/startup/seatsCap.ts @@ -1,6 +1,7 @@ import { Meteor } from 'meteor/meteor'; import type { IUser } from '@rocket.chat/core-typings'; import { Users } from '@rocket.chat/models'; +import { throttle } from 'underscore'; import { callbacks } from '../../../lib/callbacks'; import { canAddNewUser, getMaxActiveUsers, onValidateLicenses } from '../../app/license/server/license'; @@ -79,7 +80,7 @@ callbacks.add( 'check-max-user-seats', ); -async function handleMaxSeatsBanners() { +const handleMaxSeatsBanners = throttle(async function _handleMaxSeatsBanners() { const maxActiveUsers = getMaxActiveUsers(); if (!maxActiveUsers) { @@ -106,7 +107,7 @@ async function handleMaxSeatsBanners() { } else { await enableDangerBanner(); } -} +}, 10000); callbacks.add('afterCreateUser', handleMaxSeatsBanners, callbacks.priority.MEDIUM, 'handle-max-seats-banners'); diff --git a/apps/meteor/lib/utils/throttledCounter.ts b/apps/meteor/lib/utils/throttledCounter.ts new file mode 100644 index 0000000000000000000000000000000000000000..6580699b363037bc58d2a7f70e1f09bcbb2db784 --- /dev/null +++ b/apps/meteor/lib/utils/throttledCounter.ts @@ -0,0 +1,20 @@ +import { throttle } from 'underscore'; + +export function throttledCounter(fn: (counter: number) => unknown, wait: number) { + let counter = 0; + + const throttledFn = throttle( + () => { + fn(counter); + + counter = 0; + }, + wait, + { leading: false }, + ); + + return () => { + counter++; + throttledFn(); + }; +}