mirror of
https://github.com/finos/SymphonyElectron.git
synced 2024-12-28 09:51:06 -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 * as electron from 'electron';
|
||||||
|
|
||||||
|
import { isMac } from '../common/env';
|
||||||
import { logger } from '../common/logger';
|
import { logger } from '../common/logger';
|
||||||
import { config } from './config-handler';
|
import { config } from './config-handler';
|
||||||
import { windowHandler } from './window-handler';
|
import { windowHandler } from './window-handler';
|
||||||
@ -9,6 +10,7 @@ class MemoryMonitor {
|
|||||||
private memoryInfo: Electron.ProcessMemoryInfo | undefined = undefined;
|
private memoryInfo: Electron.ProcessMemoryInfo | undefined = undefined;
|
||||||
private isInMeeting: boolean;
|
private isInMeeting: boolean;
|
||||||
private canReload: boolean;
|
private canReload: boolean;
|
||||||
|
private lastReloadTime?: number;
|
||||||
|
|
||||||
private readonly maxIdleTime: number;
|
private readonly maxIdleTime: number;
|
||||||
private readonly memoryThreshold: number;
|
private readonly memoryThreshold: number;
|
||||||
@ -17,9 +19,9 @@ class MemoryMonitor {
|
|||||||
constructor() {
|
constructor() {
|
||||||
this.isInMeeting = false;
|
this.isInMeeting = false;
|
||||||
this.canReload = true;
|
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.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`);
|
logger.info(`memory-monitor: validating memory refresh conditions`);
|
||||||
const { memoryRefresh } = config.getConfigFields([ 'memoryRefresh' ]);
|
const { memoryRefresh } = config.getConfigFields([ 'memoryRefresh' ]);
|
||||||
if (!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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
(electron.powerMonitor as any).querySystemIdleTime((time) => {
|
(electron.powerMonitor as any).querySystemIdleTime((time) => {
|
||||||
const idleTime = time * 1000;
|
const idleTime = time * 1000;
|
||||||
if (!(!this.isInMeeting
|
// for MacOS use private else use residentSet
|
||||||
&& windowHandler.isOnline
|
const memoryConsumption = isMac ? (this.memoryInfo && this.memoryInfo.private) : (this.memoryInfo && this.memoryInfo.residentSet);
|
||||||
&& this.canReload
|
logger.info(`memory-monitor: Checking different conditions to see if we should auto reload the app`);
|
||||||
&& idleTime > this.maxIdleTime
|
|
||||||
&& (this.memoryInfo && this.memoryInfo.private > this.memoryThreshold))
|
logger.info(`memory-monitor: Is in meeting: `, this.isInMeeting);
|
||||||
) {
|
logger.info(`memory-monitor: Is Network online: `, windowHandler.isOnline);
|
||||||
logger.info(`memory-monitor: Not Reloading the app as
|
logger.info(`memory-monitor: Memory consumption: `, memoryConsumption);
|
||||||
application was refreshed less than a hour ago? ${this.canReload ? 'no' : 'yes'}
|
logger.info(`memory-monitor: Idle Time: `, idleTime);
|
||||||
memory consumption is ${(this.memoryInfo && this.memoryInfo.private) || 'unknown'}kb is less than? ${this.memoryThreshold}kb
|
logger.info(`memory-monitor: Last Reload time: `, this.lastReloadTime);
|
||||||
system idle tick was ${idleTime}ms is less than? ${this.maxIdleTime}ms
|
|
||||||
user was in a meeting? ${this.isInMeeting}
|
if (this.isInMeeting) {
|
||||||
is network online? ${windowHandler.isOnline}`);
|
logger.info(`memory-monitor: NOT RELOADING -> User is currently in a meeting. Meeting status from client: `, this.isInMeeting);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const mainWindow = windowHandler.getMainWindow();
|
|
||||||
if (mainWindow && windowExists(mainWindow)) {
|
if (!windowHandler.isOnline) {
|
||||||
logger.info(`memory-monitor: Reloading the app to optimize memory usage as
|
logger.info(`memory-monitor: NOT RELOADING -> Not connected to network. Network status: `, windowHandler.isOnline);
|
||||||
memory consumption is ${this.memoryInfo.private}kb is greater than? ${this.memoryThreshold}kb threshold
|
return;
|
||||||
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 (!(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 ssfWindow: ISSFWindow = window;
|
||||||
const memoryInfoFetchInterval = 60 * 60 * 1000;
|
const minMemoryFetchInterval = 4 * 60 * 60 * 1000;
|
||||||
|
const maxMemoryFetchInterval = 12 * 60 * 60 * 1000;
|
||||||
const snackBar = new SnackBar();
|
const snackBar = new SnackBar();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,6 +44,36 @@ const createAPI = () => {
|
|||||||
|
|
||||||
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
|
// When the window is completely loaded
|
||||||
ipcRenderer.on('page-load', (_event, { locale, resources, enableCustomTitleBar, isMainWindow }) => {
|
ipcRenderer.on('page-load', (_event, { locale, resources, enableCustomTitleBar, isMainWindow }) => {
|
||||||
|
|
||||||
@ -76,13 +107,7 @@ ipcRenderer.on('page-load', (_event, { locale, resources, enableCustomTitleBar,
|
|||||||
downloadManager.initDownloadManager();
|
downloadManager.initDownloadManager();
|
||||||
|
|
||||||
if (isMainWindow) {
|
if (isMainWindow) {
|
||||||
setInterval(async () => {
|
monitorMemory(getRandomTime(minMemoryFetchInterval, maxMemoryFetchInterval));
|
||||||
const memoryInfo = await process.getProcessMemoryInfo();
|
|
||||||
ipcRenderer.send(apiName.symphonyApi, {
|
|
||||||
cmd: apiCmds.memoryInfo,
|
|
||||||
memoryInfo,
|
|
||||||
});
|
|
||||||
}, memoryInfoFetchInterval);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user