1

I want to run some scheduled jobs. These jobs can take up a long time and I want to give them a timeout. When a function is already running for 60s then stop the exectuion immediately of the function and all calls from this function.

var x = function (){
    /* doing something for eventually a looong time */
}

x.kill()

Is this possible?

jfriend00
  • 683,504
  • 96
  • 985
  • 979
boop
  • 7,413
  • 13
  • 50
  • 94
  • Have you thought about using [web workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers)? – Alex McMillan Jun 06 '15 at 00:39
  • @AlexMcMillan I did not - never heard of them before. But I need to `require` nodejs modules. The modules also need to be in the same state as in the main thread. So I guess web workers aren't a good solution for this one. – boop Jun 06 '15 at 00:47

2 Answers2

1

Because node.js by itself is single threaded, no other code outside of x() will run until x() returns. So, you cannot conceptually do what you're trying to do with a single function that runs synchronously.

There are some libraries that add some sort of threading (with special limitations) that you could use. You can see this post for more details on some of those options: How to create threads in nodejs

If you show us what the code is doing inside of x(), then we could offer you some ideas on how to restructure that code to accomplish your goal. If it has asynchronous operations (or could be converted to use asynchronous operations), then x() will return and other code could run while node.js is waiting for those asynchronous operations to do their thing and you could signal to those asynchronous operations that they should stop doing their thing. But, the majority of the time would have to be waiting for asynchronous operations in order for that scheme to work.

If you can move the x() code to a separate process, then you could start a child process, give it the x() code to run and then kill the entire node child process if it doesn't finish in a certain amount of time. This is obviously a bit of a heavy-weight way to do handle this function call, but it does give you the ability to kill the whole environment if needed. It also provides process isolation if that's useful from a security or privacy point of view.

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
0

If you're using Node.js, you may consider using child_process to make asynchronous function calls which you can kill it later in case it doesn't finish in a period of time.

But this approach will need you to separate function x to another JS file, say modulex.js which implements:

function x(){
    // do whatever
}
x();

While, in your main.js (or any name you give it) where you want to start running function x in that modulex.js asynchronously and kill it later, you call it via child_process which is one of the built-in feature of Node.js:

var spawn = require('child_process').spawn;
var x = spawn('node modulex.js'); // give any particular arguments if required

x.stdout.on('data', function (data) {
    // event handler when function x finishes!

    // data = any output printed by modulex.js
});

x.stderr.on('data', function (data) {
    // event handler when function x fails!

    // data = any error printed by modulex.js
});

// Or kill the `x` after a timeout with this:
function timeout(){
    x.kill();
}

This approach will need you to redesign the architecture of your node application slightly. But this will cope with single-threaded JavaScript more efficiently.

I recommend reading this official documentation of child_process on node.js before getting started: https://nodejs.org/api/child_process.html

TaoPR
  • 5,932
  • 3
  • 25
  • 35