2

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.

4
  • You can execute shell commands with nodejs 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 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 commands like ps. 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. Commented Jan 22, 2018 at 20:38

3 Answers 3

2

There are OS-specific ways of looking at all the processes running on the current computer 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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. This looks promising. I will try this out.
@exbuddha - In testing this code, I found a few issues. I have corrected the code.
1

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

Comments

1

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") } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.