title: avoiding simultaneous execution of shell command with node.js & shelljs
body: <p>Using nodejs 8.12 on Gnu/Linux CentOS 7. Using the built-in web server, require('https'), for a simple application. </p>
  
  <p>I understand that nodejs is single threaded (single process) and there is no actual parallel execution of code. Based on my understanding, I think the http/https server will process one http request and run the handler through all synchronous statements and set up asynchronous statements to be executed later before it will return to process a subsequent request. However, with http/https libraries, you have an asynchronous code that is used to assemble the body of the request. So, we already have one callback which is executed when the body is ready ('end' event). This fact makes me think it might be possible to be in the middle of processing two or more requests simultaneously.</p>
  
  <p>As part of handling the requests, I need to execute a string of shell commands and I use the shelljs.exec library to do that. It runs synchronously, waiting until complete before returning. So, example code would look like:</p>
  
  <pre><code>const shelljs_exec = require('shelljs.exec');
  function process() {
     // bunch of shell commands in string
     var command_str = 'command1; command2; command3';
     var exec_results = shelljs_exec(command_str);
     console.log('just executed shelljs_exec command');
     var proc_results = process_results(exec_results);
     console.log(proc_results);
     // and return the response... 
  }
  </code></pre>
  
  <p>So node.js runs the shelljs_exec() and waits for completion. While it's waiting, can another request be worked on, such that there is a risk, slight, of two or more shelljs.exec invocations running at the same time? Since that could be a problem, I need to ensure only one shelljs.exec statement can be in progress at a given time. </p>
  
  <p>If that is not a correct understanding, then I was thinking I need to do something with mutex locks. Like this:</p>
  
  <pre><code>const shelljs_exec = require('shelljs.exec');
  const locks = require('locks');
  
  // Need this in global scope - so we are all dealing with the same one.
  var mutex = locks.createMutex();
  
  function await_lock(shell_commands) {
    var commands = shell_commands;
    return new Promise(getting_lock =&gt; {
      mutex.lock(got_lock_and_execute);
    });
  
    function got_lock_and_execute() {
      var exec_results = shelljs_exec(commands);
      console.log('just executed shelljs_exec command');
      mutex.unlock();
      return exec_results;
    }
  }
  
  async function process() {
    // bunch of shell commands in string
    var command_str = 'command1; command2; command3';
    exec_results = await await_lock(command_str);
    var proc_results = process_results(exec_results);
    console.log(proc_results);
  }
  </code></pre>