Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NodeJs: Cancel function call if it takes too long

In my Node.js app I need some sort of mechanism to stop a function call if it takes too long.

function testIt() { ... }

runFunctionOnlyFor(1000, testIt, function (err) {
    if (err) console.log('function call timed out');
    else console.log('function call completed successfully');
});

Now, of course the implementation of runFuncOnlyFor is unknown (to me). Any suggestions how to implement this ?

like image 389
Jeanluca Scaljeri Avatar asked Feb 11 '26 10:02

Jeanluca Scaljeri


2 Answers

I see some issues here.

1) You normally shouldn't write blocking code in Node.JS, even if it's "only" 1 second. If this is a web service with many clients, blocking for one second could have devastating performance effects.

2) Since Node.JS is effectively single-threaded I don't really see any easy way to cancel the execution after a certain amount of time unless the time-keeping is done by testit itself, since you would need a separate thread to run the function that aborts the function running in the first thread.

A better approach is likely to make the testit function async, and break it down into several steps with intermediate context switches, and periodically check for a flag or similar that may be set by runFunctionOnlyFor once a timer for the desired duration expires.

Another way is to use a child process , if that suits your purposes.

like image 106
JHH Avatar answered Feb 14 '26 00:02

JHH


You can do it by creating a proxy function:

1- Store the old function in a variable

2- Create a new function that sets a timeout with a value from a param and throw an error once it timesout.

Example:

async function testFunc (callback) {
  const res = await doSomeLogic();
  callback(null, res);
}

const oldTestFunc = testFunc;
async function proxiedTestFunc (timeout, callback) {
  const timeoutId = settimeout(() => {
    return callback("TIMEOUT", null);
  }, timeout);
  const res = await oldtestFunc();
  clearTimeout(timeoutId);
  callback(null, res);
}
like image 29
Amr Elmohamady Avatar answered Feb 13 '26 23:02

Amr Elmohamady