Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limited function calls in nodejs on same operation?

I am currently working on some scientific calculations for which my base calculation loops are executed over and over again with recursive calls as long as at least one parameter is false.

Currently my nodejs server stops at around 905 - 915th recursive function call.

The weird thing is, that it doesn't crash, nor output any error. It just stops doing anything -> no more logs etc.

Is this some protection behaviour from node to avoid overflow?

I am struggling with this for a few weeks now whilst trying to limit the "loops" with an as intelligent as possible software.

Thank you for your help & advice. Greetings Noa.

As requested I provide some abstraction of my actual code

I hope this helps. I cannot put my original code on here because it consists of more than 1.5k lines - theres a lot to check. But the below example covers the base logic behind the recursive call.

// Contains objects which contain an array
// which represents the amount of the ex_obj terms
var amount = {
  a:[10,10],
  b:[7.5,7.5],
  c:[2.5,2.5,2.5,2.5]
}

// Contains objects, which contain an array of other objects
// that represent some selection
// Each object in an array consists of different values per attribute per 1 amount
var ex_obj = {
  a: [
    {aa: 1.41, ab: 0.143, ac: 0.5},
    {aa: 1.30, ab: 1.43, ac: 0.42}
  ],
  b: [
    {aa: 0.32, ab: 5.54, ac: 1.3},
    {aa: 0.33, ab: 4.49, ac: 2.5}
  ],
  c: [
    {aa: 0.54, ab: 1.4, ac: 3.5},
    {aa: 0.39, ab: 1.434, ac: 3.91},
    {aa: 0.231, ab: 1.44324, ac: 2.91},
    {aa: 0.659, ab: 1.554, ac: 3.9124},
  ]
}

// Here we have an object that represents
// the "to be" state which should be achieved
var should_be ={
  aa: 14.534,
  ab: 3.43,
  ac: 5.534
}

function calculate(){
  // Now we want to mulitply the amount object values with
  // the ex_obj values

  for(let prop in ex_obj){
    for(let i = 0, i < ex_obj[prop].length, i++){
      for(let propa in ex_obj[prop][i]){
        // here every aa,ab,ac gets mulitplied with the
        // contains of the amount obj for the matching
        // propertyname
      }
    }
  }

  // the next step is to check if the sum of all ex_obj property
  // child values per aa, ab and ac match the should_be propertie values

  // if everything is above the should_be and not too high then the
  // programm can stop here and print out the amount obj.

  // if the sum of the ex_obj properties is too little
  // compared to the should_be obj
  // we need to check which property is too little
  // e.g. aa is too little
  // then we check where aa in the ex_obj per 1 value is
  // the highest
  // then we increment the matching amount property child
  // and start calculate() again

  // same procedure for - if something is too much
}
like image 567
noa-dev Avatar asked Mar 20 '16 19:03

noa-dev


People also ask

How does node js handle concurrent tasks?

To address these issues, Node. JS uses a single thread with an event-loop. In this way, Node can handle 1000s of concurrent connections without any of the traditional detriments associated with threads. There is essentially no memory overhead per-connection, and there is no context switching.

How many callback functions can ever be executing at any time?

As long as the callback code is purely sync than no two functions can execute parallel.


2 Answers

Since your code isn't complete it's hard to say exactly what's going wrong. If you exceed node's call stack limit you will get an exception, although 1000 recursions isn't normally a problem.

It might be that you're choking the Node.js event-loop. Instead of directly calling the recursive function, you can try to call

process.nextTick(function(){calculate()})
like image 190
Rudolf Meijering Avatar answered Oct 13 '22 10:10

Rudolf Meijering


It's not suprised that direct recursive call will result in stack overflow, however, it seems that frequent function calls will get node hang up(BTW, I don't know why this happens :( ).

For example, the following script get frozen at around 4k ~ 5k loops on my machine with 1.6 GHz CPU and 3.3 GiB memory, and node keeps swallowing my available memory after that.

var i = 0;
function cal() {
   console.log(++i);
   process.nextTick(cal);
}
cal();

But if I changed process.nextTick(cal); to setTimeout(cal, 0);, everything works fine.

So as for your question, I think you can use something like setTimeout(calculate, 100) in your script to prevent recursive call and defer it slightly.

like image 32
knight42 Avatar answered Oct 13 '22 11:10

knight42