mirror of
https://github.com/finos/SymphonyElectron.git
synced 2024-12-27 17:31:36 -06:00
fix: SDA-1520 (Optimize memory refresh logic & make it randomize) (#782)
* SDA-1520 - Optimize memory refresh logic & make it randomize * SDA-1520 - Change attributes, for MacOS use private else use residentSet
This commit is contained in:
parent
a28bdb69b1
commit
114d6d897a
@ -1,5 +1,6 @@
|
||||
import * as electron from 'electron';
|
||||
|
||||
import { isMac } from '../common/env';
|
||||
import { logger } from '../common/logger';
|
||||
import { config } from './config-handler';
|
||||
import { windowHandler } from './window-handler';
|
||||
@ -9,6 +10,7 @@ class MemoryMonitor {
|
||||
private memoryInfo: Electron.ProcessMemoryInfo | undefined = undefined;
|
||||
private isInMeeting: boolean;
|
||||
private canReload: boolean;
|
||||
private lastReloadTime?: number;
|
||||
|
||||
private readonly maxIdleTime: number;
|
||||
private readonly memoryThreshold: number;
|
||||
@ -17,9 +19,9 @@ class MemoryMonitor {
|
||||
constructor() {
|
||||
this.isInMeeting = false;
|
||||
this.canReload = true;
|
||||
this.maxIdleTime = 4 * 60 * 60 * 1000; // 4 hours
|
||||
this.maxIdleTime = 4 * 60 * 60 * 1000; // user activity threshold 4 hours
|
||||
this.memoryThreshold = 800 * 1024; // 800MB
|
||||
this.memoryRefreshThreshold = 60 * 60 * 1000; // 1 hour
|
||||
this.memoryRefreshThreshold = 24 * 60 * 60 * 1000; // 24 hour
|
||||
}
|
||||
|
||||
/**
|
||||
@ -51,40 +53,62 @@ class MemoryMonitor {
|
||||
logger.info(`memory-monitor: validating memory refresh conditions`);
|
||||
const { memoryRefresh } = config.getConfigFields([ 'memoryRefresh' ]);
|
||||
if (!memoryRefresh) {
|
||||
logger.info(`memory-monitor: memory refresh is disabled in the config, not going to refresh!`);
|
||||
logger.info(`memory-monitor: memory reload is disabled in the config, not going to refresh!`);
|
||||
return;
|
||||
}
|
||||
|
||||
(electron.powerMonitor as any).querySystemIdleTime((time) => {
|
||||
const idleTime = time * 1000;
|
||||
if (!(!this.isInMeeting
|
||||
&& windowHandler.isOnline
|
||||
&& this.canReload
|
||||
&& idleTime > this.maxIdleTime
|
||||
&& (this.memoryInfo && this.memoryInfo.private > this.memoryThreshold))
|
||||
) {
|
||||
logger.info(`memory-monitor: Not Reloading the app as
|
||||
application was refreshed less than a hour ago? ${this.canReload ? 'no' : 'yes'}
|
||||
memory consumption is ${(this.memoryInfo && this.memoryInfo.private) || 'unknown'}kb is less than? ${this.memoryThreshold}kb
|
||||
system idle tick was ${idleTime}ms is less than? ${this.maxIdleTime}ms
|
||||
user was in a meeting? ${this.isInMeeting}
|
||||
is network online? ${windowHandler.isOnline}`);
|
||||
// for MacOS use private else use residentSet
|
||||
const memoryConsumption = isMac ? (this.memoryInfo && this.memoryInfo.private) : (this.memoryInfo && this.memoryInfo.residentSet);
|
||||
logger.info(`memory-monitor: Checking different conditions to see if we should auto reload the app`);
|
||||
|
||||
logger.info(`memory-monitor: Is in meeting: `, this.isInMeeting);
|
||||
logger.info(`memory-monitor: Is Network online: `, windowHandler.isOnline);
|
||||
logger.info(`memory-monitor: Memory consumption: `, memoryConsumption);
|
||||
logger.info(`memory-monitor: Idle Time: `, idleTime);
|
||||
logger.info(`memory-monitor: Last Reload time: `, this.lastReloadTime);
|
||||
|
||||
if (this.isInMeeting) {
|
||||
logger.info(`memory-monitor: NOT RELOADING -> User is currently in a meeting. Meeting status from client: `, this.isInMeeting);
|
||||
return;
|
||||
}
|
||||
const mainWindow = windowHandler.getMainWindow();
|
||||
if (mainWindow && windowExists(mainWindow)) {
|
||||
logger.info(`memory-monitor: Reloading the app to optimize memory usage as
|
||||
memory consumption is ${this.memoryInfo.private}kb is greater than? ${this.memoryThreshold}kb threshold
|
||||
system idle tick was ${idleTime}ms is greater than ${this.maxIdleTime}ms
|
||||
user was in a meeting? ${this.isInMeeting}
|
||||
is network online? ${windowHandler.isOnline}`);
|
||||
windowHandler.setIsAutoReload(true);
|
||||
mainWindow.reload();
|
||||
this.canReload = false;
|
||||
setTimeout(() => {
|
||||
this.canReload = true;
|
||||
}, this.memoryRefreshThreshold);
|
||||
|
||||
if (!windowHandler.isOnline) {
|
||||
logger.info(`memory-monitor: NOT RELOADING -> Not connected to network. Network status: `, windowHandler.isOnline);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(memoryConsumption && memoryConsumption > this.memoryThreshold)) {
|
||||
logger.info(`memory-monitor: NOT RELOADING -> Memory consumption ${memoryConsumption} is lesser than the threshold ${this.memoryThreshold}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(idleTime > this.maxIdleTime)) {
|
||||
logger.info(`memory-monitor: NOT RELOADING -> User is not idle for: `, idleTime);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.canReload) {
|
||||
logger.info(`memory-monitor: NOT RELOADING -> Already refreshed at: `, this.lastReloadTime);
|
||||
return;
|
||||
}
|
||||
|
||||
const mainWindow = windowHandler.getMainWindow();
|
||||
if (!(mainWindow && windowExists(mainWindow))) {
|
||||
logger.info(`memory-monitor: NOT RELOADING -> Main window doesn't exist!`);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info(`memory-monitor: RELOADING -> auto reloading the app as all the conditions are satisfied`);
|
||||
|
||||
windowHandler.setIsAutoReload(true);
|
||||
mainWindow.reload();
|
||||
this.canReload = false;
|
||||
this.lastReloadTime = new Date().getTime();
|
||||
setTimeout(() => {
|
||||
this.canReload = true;
|
||||
}, this.memoryRefreshThreshold); // prevents multiple reloading of the client within 24hrs
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,8 @@ interface ISSFWindow extends Window {
|
||||
}
|
||||
|
||||
const ssfWindow: ISSFWindow = window;
|
||||
const memoryInfoFetchInterval = 60 * 60 * 1000;
|
||||
const minMemoryFetchInterval = 4 * 60 * 60 * 1000;
|
||||
const maxMemoryFetchInterval = 12 * 60 * 60 * 1000;
|
||||
const snackBar = new SnackBar();
|
||||
|
||||
/**
|
||||
@ -43,6 +44,36 @@ const createAPI = () => {
|
||||
|
||||
createAPI();
|
||||
|
||||
/**
|
||||
* Returns a random number that is between (min - max)
|
||||
* if min is 4hrs and max is 12hrs then the
|
||||
* returned value will be a random b/w 4 - 12 hrs
|
||||
*
|
||||
* @param min {number} - millisecond
|
||||
* @param max {number} - millisecond
|
||||
*/
|
||||
const getRandomTime = (min, max) => {
|
||||
min = Math.ceil(min);
|
||||
max = Math.floor(max);
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
};
|
||||
|
||||
/**
|
||||
* Monitory memory with a randomized time
|
||||
*
|
||||
* @param time
|
||||
*/
|
||||
const monitorMemory = (time) => {
|
||||
setTimeout(async () => {
|
||||
const memoryInfo = await process.getProcessMemoryInfo();
|
||||
ipcRenderer.send(apiName.symphonyApi, {
|
||||
cmd: apiCmds.memoryInfo,
|
||||
memoryInfo,
|
||||
});
|
||||
monitorMemory(getRandomTime(minMemoryFetchInterval, maxMemoryFetchInterval));
|
||||
}, time);
|
||||
};
|
||||
|
||||
// When the window is completely loaded
|
||||
ipcRenderer.on('page-load', (_event, { locale, resources, enableCustomTitleBar, isMainWindow }) => {
|
||||
|
||||
@ -76,13 +107,7 @@ ipcRenderer.on('page-load', (_event, { locale, resources, enableCustomTitleBar,
|
||||
downloadManager.initDownloadManager();
|
||||
|
||||
if (isMainWindow) {
|
||||
setInterval(async () => {
|
||||
const memoryInfo = await process.getProcessMemoryInfo();
|
||||
ipcRenderer.send(apiName.symphonyApi, {
|
||||
cmd: apiCmds.memoryInfo,
|
||||
memoryInfo,
|
||||
});
|
||||
}, memoryInfoFetchInterval);
|
||||
monitorMemory(getRandomTime(minMemoryFetchInterval, maxMemoryFetchInterval));
|
||||
}
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user