Files
SymphonyElectron/js/memoryMonitor.js

196 lines
6.3 KiB
JavaScript

'use strict';
const eventEmitter = require('./eventEmitter');
const log = require('./log.js');
const logLevels = require('./enums/logLevels.js');
const { getMainWindow, setIsAutoReload, getIsOnline } = require('./windowMgr');
const { getConfigField } = require('./config');
const maxMemory = 800;
const defaultInterval = 30 * 1000;
const memoryRefreshThreshold = 60 * 60 * 1000;
const cpuUsageThreshold = 5;
let isInMeeting = false;
let canReload = true;
let appMinimizedTimer;
let powerMonitorTimer;
let preloadMemory;
let preloadWindow;
// once a minute
setInterval(gatherMemory, 1000 * 60);
/**
* Gathers system memory and logs it to the remote system
*/
function gatherMemory() {
let memory = process.getProcessMemoryInfo();
let details =
'workingSetSize: ' + memory.workingSetSize +
' peakWorkingSetSize: ' + memory.peakWorkingSetSize +
' privatesBytes: ' + memory.privatesBytes +
' sharedBytes: ' + memory.sharedBytes;
log.send(logLevels.INFO, details);
}
/**
* Method that checks memory usage every minute
* and verify if the user in inactive if so it reloads the
* application to free up some memory consumption
*/
function optimizeMemory() {
if (!preloadMemory || !preloadMemory.memoryInfo || !preloadMemory.cpuUsage) {
log.send(logLevels.INFO, `Memory info not available`);
return;
}
const memoryConsumed = (preloadMemory.memoryInfo && preloadMemory.memoryInfo.workingSetSize / 1024) || 0;
const cpuUsagePercentage = preloadMemory.cpuUsage.percentCPUUsage;
const activeNetworkRequest = preloadMemory.activeRequests === 0;
if (memoryConsumed > maxMemory
&& cpuUsagePercentage <= cpuUsageThreshold
&& !isInMeeting
&& getIsOnline()
&& canReload
&& activeNetworkRequest
) {
getConfigField('memoryRefresh')
.then((enabled) => {
if (enabled) {
const mainWindow = getMainWindow();
if (mainWindow && !mainWindow.isDestroyed()) {
setIsAutoReload(true);
log.send(logLevels.INFO, `Reloading the app to optimize memory usage as
memory consumption was ${memoryConsumed}
CPU usage percentage was ${preloadMemory.cpuUsage.percentCPUUsage}
user was in a meeting? ${isInMeeting}
pending network request on the client was ${preloadMemory.activeRequests}
is network online? ${getIsOnline()}`);
mainWindow.reload();
// do not refresh for another 1hrs
canReload = false;
setTimeout(() => {
canReload = true;
}, memoryRefreshThreshold);
}
} else {
log.send(logLevels.INFO, `Memory refresh not enabled by the user so Not Reloading the app`);
}
});
} else {
log.send(logLevels.INFO, `Not Reloading the app as
memory consumption was ${memoryConsumed}
CPU usage percentage was ${preloadMemory.cpuUsage.percentCPUUsage}
user was in a meeting? ${isInMeeting}
pending network request on the client was ${preloadMemory.activeRequests}
is network online? ${getIsOnline()}`);
}
}
/**
* Sets the current user meeting status
* @param meetingStatus - Whether user is in an active meeting
*/
function setIsInMeeting(meetingStatus) {
isInMeeting = meetingStatus;
}
/**
* Sets preload memory info and calls optimize memory func
*
* @param memoryInfo - memory consumption of the preload main script
* @param cpuUsage - CPU usage of the preload main script
* @param activeRequests - pending active network requests on the client
*/
function setPreloadMemoryInfo(memoryInfo, cpuUsage, activeRequests) {
log.send(logLevels.INFO, 'Memory info received from preload process now running optimize memory logic');
preloadMemory = { memoryInfo, cpuUsage, activeRequests };
optimizeMemory();
}
/**
* Called whenever the application is minimized
* and waits for 30s to optimize memory
*/
eventEmitter.on('appMinimized', () => {
appMinimizedTimer = setTimeout(() => {
const mainWindow = getMainWindow();
if (mainWindow && !mainWindow.isDestroyed() && mainWindow.isMinimized()) {
log.send(logLevels.INFO, 'Application is minimised for more than 30s so calling requestMemoryInfo');
requestMemoryInfo();
}
}, defaultInterval);
});
/**
* Called whenever the application is restored from minimized state
*
* Clears appMinimizedTimer if the app is restored within 30s
* from minimized state
*/
eventEmitter.on('appRestored', () => {
log.send(logLevels.INFO, 'Application was restored from minimized state');
setIsAutoReload(false);
if (appMinimizedTimer) {
clearTimeout(appMinimizedTimer);
}
});
/**
* Called whenever the system in locked
* and waits for 30s to optimize memory
*/
eventEmitter.on('sys-locked', () => {
log.send(logLevels.INFO, 'System screen was locked');
powerMonitorTimer = setTimeout(() => {
log.send(logLevels.INFO, 'System screen was locked for more than 30s so calling requestMemoryInfo');
requestMemoryInfo();
}, defaultInterval);
});
/**
* Called whenever the system in locked
*
* Clears powerMonitorTimer if the system is unlocked within 30s
* from locked state
*/
eventEmitter.on('sys-unlocked', () => {
log.send(logLevels.INFO, 'System screen was unlocked');
setIsAutoReload(false);
if (powerMonitorTimer) {
clearTimeout(powerMonitorTimer);
}
});
/**
* Sets the preload window
*
* @param win - preload window
*/
function setPreloadWindow(win) {
log.send(logLevels.INFO, 'Preload window registered');
preloadWindow = win;
}
/**
* Request memory info from the registered preload window
* which invokes the optimize memory func
*/
function requestMemoryInfo() {
if (preloadWindow) {
log.send(logLevels.INFO, 'Requesting memory information from the preload script');
preloadWindow.send('memory-info-request');
}
}
module.exports = {
setIsInMeeting,
setPreloadMemoryInfo,
setPreloadWindow,
};