const EventEmitter = require('events'), | |
ps = require('xps'); | |
class ProcessListener extends EventEmitter { | |
constructor() { | |
super(); | |
let listenTimeout = 1000; | |
let listenTimeoutId = false; | |
let running = false; | |
let previousProcesses = []; | |
let previousProcessesById = {}; | |
const executeListenIntervalFn = () => { | |
getProcessListFn((processes, newProcesses, closedProcesses) => { | |
if (running) { | |
// notify the listeners about the new & closed processes | |
newProcesses.forEach(process => this.emit('start', process)); | |
closedProcesses.forEach(process => this.emit('stop', process)); | |
this.emit('list', processes); | |
// schedule the next call | |
listenTimeoutId = setTimeout(executeListenIntervalFn, listenTimeout); | |
} | |
}); | |
}; | |
const getProcessListFn = cb => { | |
ps.list().fork( | |
error => { | |
throw error | |
}, | |
processes => { | |
const processesById = {}; | |
processes.forEach(process => processesById[process.pid] = process); | |
// find the new processes | |
const newProcesses = processes.filter(process => previousProcessesById[process.pid] == null); | |
const closedProcesses = previousProcesses.filter(process => processesById[process.pid] == null); | |
previousProcesses = processes; | |
previousProcessesById = processesById; | |
if (cb) { | |
cb(processes, newProcesses, closedProcesses); | |
} | |
} | |
); | |
}; | |
this.getRunningProcesses = () => { | |
return new Promise(resolve => { | |
if (previousProcesses.length > 0) { | |
return resolve(previousProcesses); | |
} | |
if (running) { | |
// wait for the first 'list', at that point we have the processes | |
this.once('list', () => resolve(previousProcesses)); | |
} else { | |
getProcessListFn((processes, newProcesses, closedProcesses) => { | |
resolve(processes); | |
}); | |
} | |
}); | |
}; | |
this.setListenTimeout = value => { | |
listenTimeout = value; | |
}; | |
this.stop = () => { | |
running = false; | |
clearTimeout(listenTimeoutId); | |
}; | |
this.start = (listenTimeoutValue = 1000) => { | |
if (running) { | |
return; | |
} | |
listenTimeout = listenTimeoutValue; | |
running = true; | |
executeListenIntervalFn(); | |
}; | |
} | |
}; | |
module.exports = new ProcessListener(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment