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:
Kiran Niranjan 2019-09-12 16:04:39 +05:30 committed by Vishwas Shashidhar
parent a28bdb69b1
commit 114d6d897a
2 changed files with 85 additions and 36 deletions

View File

@ -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
});
}
}

View File

@ -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));
}
});