0

I'm working on a node.js API that needs to start/run a time-intensive javaScript file when a certain endpoint is hit. I've got this working, but what I'm now looking for is a way to stop the script from running again if it's already running and the endpoint gets hit again.

I tried to use the child_process library, hoping that if the script is being executed as a separate process from the main node.js app, it would be easier to check if the script is already running. I thought of using the process exit event for the child process that I created, but this proved to be unhelpful because it would only run once the process was done, but didn't help in checking if it was currently running.

I also had considered cron jobs, but there doesn't seem to be a good way to just start a cron job on command without making a time-based schedule.

In another project, I used a database and simply created a new row in a table to indicate whether the script was available to run, currently running, or finished. I could definitely do it this way again, but I'm trying to keep this project as light as possible.

Lastly, I did consider just adding some global state variable that would indicate if the process is running or not, but wasn't sure if that was the best method.

So, if anyone either knows a way to check if a child process script is currently running or has a better way of achieving what I'm trying to achieve here, any direction would be helpful.

Knight Steele
  • 169
  • 4
  • 14
  • In MineOS the author finds Java instances of Minecraft. Looks like he keeps track of the process id per-instance and checks that it exists or not. Similar to your global variable idea. – Peter Dec 27 '21 at 18:12

1 Answers1

1

You can use a variable, and it doesn't even have to be global!

class MySingletonProcess {
  constructor() {
    this.isBusy = false;
    this.spawnProcess = this.spawnProcess.bind(this);
  }

  doProcess() {
    console.log("Doing process...");
    // fake async stuff...
    return new Promise((resolve) => {
      setTimeout(() => {
        this.isBusy = false;
        resolve();
      }, 2500);
    });
  }

  spawnProcess() {
    if (this.isBusy) {
      console.log("I'm busy!");
      return;
    } else {
      this.isBusy = true;
      this.doProcess();
    }
  }
}

const processSingleton = new MySingletonProcess();
const button = document.getElementById("button");
button.addEventListener("click", processSingleton.spawnProcess);
<button id="button">Click Me To Spawn Process</button>
Brendan Bond
  • 1,737
  • 1
  • 10
  • 8
  • Interesting. I could add this as a utility class that gets initialized when the app starts, then accessed in the service that starts the process. I'll give this a shot and get back to you. – Knight Steele Dec 27 '21 at 21:00
  • Just tried out your solution and it worked perfectly! I had to change a few things here and there to work with my current code, but ultimately it was the same idea. Thanks for your help! This method is significantly simpler and more efficient than the other methods I tried previously. – Knight Steele Dec 27 '21 at 21:56
  • Glad to hear it! – Brendan Bond Dec 27 '21 at 22:41