SymphonyElectron/src/app/memory-monitor.ts

127 lines
4.8 KiB
TypeScript

import * as electron from 'electron';
import { isMac } from '../common/env';
import { logger } from '../common/logger';
import { CloudConfigDataTypes, config } from './config-handler';
import { windowHandler } from './window-handler';
import { windowExists } from './window-utils';
class MemoryMonitor {
private memoryInfo: Electron.ProcessMemoryInfo | undefined = undefined;
private isInMeeting: boolean;
private canReload: boolean;
private lastReloadTime?: number;
private memoryThreshold: number;
private readonly maxIdleTime: number;
private readonly memoryRefreshThreshold: number;
constructor() {
this.isInMeeting = false;
this.canReload = true;
this.maxIdleTime = 4 * 60 * 60 * 1000; // user activity threshold 4 hours
this.memoryThreshold = 800 * 1024; // 800MB
this.memoryRefreshThreshold = 24 * 60 * 60 * 1000; // 24 hour
}
/**
* Sets process memory from ipc events every hour
* and refreshes the client if the conditions passes
*
* @param memoryInfo {Electron.ProcessMemoryInfo}
*/
public setMemoryInfo(memoryInfo: Electron.ProcessMemoryInfo): void {
this.memoryInfo = memoryInfo;
logger.info(`memory-monitor: setting memory info to ${JSON.stringify(memoryInfo)}`);
this.validateMemory();
}
/**
* Sets the web app's RTC meeting status
*
* @param isInMeeting {boolean} whether user is in an active RTC meeting
*/
public setMeetingStatus(isInMeeting: boolean): void {
this.isInMeeting = isInMeeting;
logger.info(`memory-monitor: setting meeting status to ${isInMeeting}`);
}
/**
* Sets the memory threshold
*
* @param memoryThreshold
*/
public setMemoryThreshold(memoryThreshold: number): void {
this.memoryThreshold = memoryThreshold * 1024;
}
/**
* Validates the predefined conditions and refreshes the client
*/
private validateMemory(): void {
logger.info(`memory-monitor: validating memory refresh conditions`);
const { memoryRefresh } = config.getConfigFields([ 'memoryRefresh' ]);
if (memoryRefresh !== CloudConfigDataTypes.ENABLED) {
logger.info(`memory-monitor: memory reload is disabled in the config, not going to refresh!`);
return;
}
const time = electron.powerMonitor.getSystemIdleTime();
const idleTime = time * 1000;
// 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;
}
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
}
}
const memoryMonitor = new MemoryMonitor();
export { memoryMonitor };