Is there a way to programmatically detect if a node.js process (or script) is already running on the machine?
I want to achieve this from the node script itself instead of relying on shell scripts or other ways of querying processes on the operating system. I know that this is possible in many programming languages such as Java and C# (using Mutex class for example). I am looking for an equivalent solution for Node.js projects.
Is there a way to programmatically detect if a node.js process (or script) is already running on the machine?
I want to achieve this from the node script itself instead of relying on shell scripts or other ways of querying processes on the operating system. I know that this is possible in many programming languages such as Java and C# (using Mutex class for example). I am looking for an equivalent solution for Node.js projects.
Share Improve this question asked Jan 22, 2018 at 20:08 exbuddhaexbuddha 6331 gold badge9 silver badges19 bronze badges 4- You can execute shell mands with nodejs – Luca Kiebel Commented Jan 22, 2018 at 20:13
-
Did you search
npm
or Google? I immediately found a variety of packages that do this in various ways: find-process being the first result – arthurakay Commented Jan 22, 2018 at 20:21 -
@Luca True. I don't know if there is a reliable way to query all types of operating systems for running processes and get an accurate result. I understand there are some boundary cases that can cause problems using shell mands like
ps
. – exbuddha Commented Jan 22, 2018 at 20:22 - @arthurakay I have found a few solutions out there. I will take a closer look at find-process. Thanks. I am also interested to learn if and how node supports this scenario internally (with just the default modules), if at all possible. – exbuddha Commented Jan 22, 2018 at 20:38
3 Answers
Reset to default 2There are OS-specific ways of looking at all the processes running on the current puter so you could use that (by running an external process as a child_process) to see if your server is already running.
But, for a cross platform mechanism, you can just put a little http server (I call a probe server) into your process and then see if that server responds. If it does, then your app is already running. If not, then it's not.
So, put this into your app:
// pick some port not already in use locally
const probePort = 8001;
const probePath = '/probe';
const http = require('http');
const rp = require('request-promise');
// see if our probe server is already running
rp({
uri: `http://localhost:${probePort}${probePath}`,
resolveWithFullResponse: true
}).then(res => {
if (res.statusCode === 200) {
console.log(`Our server already running in another process`);
process.exit(1);
} else {
throw new Error(`statusCode ${res.statusCode}`)
}
}).catch(err => {
// our process is not already running
// start our own copy of the probeServer
const server = http.createServer((req, res) => {
if (req.url === probePath) {
res.statusCode = 200;
res.end("ok");
} else {
res.statusCode = 404;
res.end("err");
}
});
server.listen(probePort);
// make sure this server does not keep the process running
server.unref();
// proceed with the rest of your process initialization here
console.log("Our server not already running, so we can now start ours");
setInterval(() => {
console.log("still running");
}, 1000);
});
Note: If you already have an http server in your app, then you can just create a special probePath route in that server that responds with a 200 status and test that rather than creating another http server.
If you're looking to monitor the nodejs process, there are plenty of good libraries out there such as foreverjs, pm2, etc. However, to answer your question more directly, you could do this by forking your process from within a node script (another process effectively):
var exited = false;
var cp = require('child_process');
var superProcess = cp.fork('./my-super-process');
superProcess.on('exit', (code, signal) => {
exited = true;
});
setInterval(function() {
if (exited) {
console.log('is gone :(')
} else {
console.log('still running ...')
}
}, 1000);
If you can somehow know the process id (PID) of your targeting PID (e.g., your server.js
may always store the PID name in server.pid
file), you can use is-running
package to know if it is running.
var _ = require('underscore')
var sh = require('shelljs')
var isRunning = require('is-running')
if(! _.contains(sh.ls("."), 'server.pid')){ // If PID file does not exist
console.log("PID file does not exist.")
} else { // PID file exists
let pid = sh.cat('server.pid').stdout
if(!isRunning(pid)){
console.log("server.js is not running")
} else {
console.log("server.js is running")
}
}
Or if you target any arbitrary process, how about this?
if(sh.exec('ps aux', {silent: true}).grep('npm').stdout != "\n"){
console.log("some npm process is running")
}