9

I have a domain exception handler (wrapper for nightwatch tests).

my exception handler wrapper

var domainError = function(func) {

    return function() {
      var d = domain.create().on('error', function(err) {
        console.error(err.stack);
      });

      d.enter();
      try {
        return func.apply(this, arguments);
      }
      catch (err) {
        //do something with the err
      }
      d.exit();
    }
};

I am trying to set timeouts so that return func.apply(this, arguments); doesn't take forever.

Could anyone suggest how I can add timeouts and make the domain end the function and exit, if it exceeds timeout?

2
  • does that func work synchronously? Commented Apr 21, 2015 at 13:11
  • yes. domainerror function works synchronously..@MustafaDokumacı Commented Apr 21, 2015 at 21:58

2 Answers 2

7
+50

This is impossible in Node's concurrency model. There are no "interrupts" - multiprocessing is done cooperatively. If you look at it from the other side - you get a really powerful guarantee that your code will almost always run to completion.

You can spawn another child process and then preempt that (since processes support preemption).


The easiest way to terminate a synchronous function is to execute it in its own "isolate" - meaning it can be killed. Note that this is not as performant as making a dedicated worker "process" and using async io to communicate with it - which is probably faster - but this is easier.

var vm = require('vm'); // get the VM module

// when you want to run a bit 
function withError(func, context, timeout){
     var ctx = vm.createContext(context);
     var code = func.toString().slice(12).slice(0,-2)
     return vm.runInContext(code, ctx, {
        timeout: timeout,
        displayErrors: true; // to log, like in your version
     });
}

Note that this code means the function has no access to closure scope or arguments, so everything needs to be in its scope - it's not as big of an issue as you might think since you can convert:

function doFoo(x, y){
    return x + y + z; // z is from closure
}

Into

function doFoo(){
    return this.x + this.y + this.z;
}

And call it as

withError(doFoo, {x:x, y:y, z:z }, 2000); // 2000 ms timeout

This can also be better automated by using a lexical analysis tool that generates a syntax tree.

If I may suggest an alternative - write your func in a way that it can yield control - cooperative multitasking is a lot easier and less error prone in these cases.

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

Comments

-3

or else use npm -install timer-stopwatch

timer stopwatch

cool ??

5 Comments

I don't think you understood the problem. This has nothing to do with any of those, this is about server-side JavaScript, and stopping synchronous code...
Clearly the answer does not address the question.
Does node.js is server-side and source code is "like" javascript and uses same paradigms as client-side ?
No, events work differently from the DOM (no preventDefault etc) and no jQuery... Even if they worked the same way - this would still be irrelevant.
it's a synchronous call...is it what you expected ?? But, i understand that the above code on("error") is similar as a delegate in C#.NET. And for delegates in c#, you are able to write something that : a.Error += func_error; thus, a.Error -= func_error is for removing the delegate; to prevent to rerun the function and adding twice the same func_error, you should remove the old delegate call first. C# delegate are synchronous calls; even, jQuery paradigms are synchronous calls too. What's wrong ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.