2016-03-20 4 views
5

Ich arbeite gerade an einigen wissenschaftlichen Berechnungen, bei denen meine Basisrechenschleifen bei rekursiven Aufrufen immer wieder ausgeführt werden, solange mindestens ein Parameter falsch ist.Begrenzte Funktion ruft Nodejs bei gleicher Operation auf?

Derzeit stoppt mein Nodejs-Server bei etwa 905 - 915. rekursiven Funktionsaufruf.

Die seltsame Sache ist, dass es nicht abstürzt, noch irgendeinen Fehler ausgibt. Es hört einfach auf irgendetwas zu tun -> keine Protokolle mehr.

Ist dies ein Schutzverhalten von Knoten, um Überlauf zu vermeiden?

Ich kämpfe jetzt seit ein paar Wochen mit dem Versuch, die "Schleifen" mit einer so intelligenten wie möglichen Software zu begrenzen.

Vielen Dank für Ihre Hilfe & Beratung. Grüße Noa.

Da bat ich

Ich hoffe, das hilft einige Abstraktion von meinem eigentlichen Code bereitzustellen. Ich kann meinen Originalcode hier nicht eingeben, da er aus mehr als 1.5k Zeilen besteht - es gibt viel zu prüfen. Das folgende Beispiel deckt jedoch die Basislogik hinter dem rekursiven Aufruf ab.

// 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 
} 
+1

Node macht es relativ einfach, rekursive Aufrufe durch asynchrone Aufrufe zu ersetzen und Stapelwachstum zu vermeiden. Stellen Sie mehr Details und Beispielcode zur Verfügung ... – Amit

+0

Ich bezweifle eher, dass wir Ihnen helfen können, ohne den Code zu sehen. Der Stapelüberlauf funktioniert sehr gut mit Fragen, die echten Code enthalten, und nicht so gut mit konzeptionellen Fragen ohne Code. – jfriend00

+0

Ich habe meine Frage aktualisiert –

Antwort

5

Da Ihr Code nicht vollständig ist, ist es schwer zu sagen, was genau falsch läuft. Wenn Sie das Call-Stack-Limit des Knotens überschreiten, erhalten Sie eine Ausnahme, obwohl 1000 Rekursionen normalerweise kein Problem darstellen.

Es kann sein, dass Sie die Node.js-Ereignisschleife ersticken. Anstatt die rekursive Funktion aufrufen, können Sie

process.nextTick(function(){calculate()}) 
+0

Danke ich werde diese Methode heute versuchen! –

+0

Es stoppt nicht mehr die Ausführung der Funktion, sondern endet in einer Endlosschleife - was möglicherweise der Grund dafür ist, dass der Standardfunktionsaufruf nach einigen Schleifen ohne ein anderes Muster gestoppt wurde. –

+0

Ich bin froh, dass Sie auf die richtige Richtung hingewiesen haben könnten –

1

zu nennen versuchen Es ist nicht überrascht, dass die direkte rekursive Aufruf in Stapelüberlauf führen, jedoch scheint es, dass häufige Funktionsaufrufe Knoten auflegen (BTW bekommen, ich Ich weiß nicht, warum das passiert :().

Zum Beispiel wird das folgende Skript bei etwa 4k ~ 5k Schleifen auf meinem Rechner mit 1,6 GHz CPU und 3,3 GiB Speicher eingefroren, und Knoten schluckt meinen verfügbaren Speicher danach .

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

Aber wenn ich 0 ändertebis setTimeout(cal, 0);, alles funktioniert gut.

So wie für Ihre Frage, ich denke, Sie können etwas wie setTimeout(calculate, 100) in Ihrem Skript verwenden, um rekursive Aufruf zu verhindern und es leicht verschieben.

+0

Der process.nextTick hat es für mich getan.Obwohl ich jetzt in einer Endlosschleife bin - aber das könnte ein Programmierfehler an meinem Ende sein. :) –

Verwandte Themen