2016-01-28 54 views
0

我有一个nodejs程序只是简单地将一个字段从一个集合复制到另一个集合。我写了两个。一个拷贝字段命名(字符串),另一个拷贝ids(字符串数组)。该集合并不大,大约只有900个表单要迭代。我可以看到它运行和保存的一些形式,但我不明白为什么会发生错误的程序继续运行:nodejs使用猫鼬错误:致命错误:CALL_AND_RETRY_LAST分配失败 - 进程内存不足

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory 

下面是程序:

var mongoose = require('mongoose'), 
    config = require('../modules/system/node-js/parseConfig'), 
    schemas = require('../modules/system/node-js/schemas.js'), 
    cde_schemas = require('../modules/cde/node-js/schemas'), 
    form_schemas = require('../modules/form/node-js/schemas'), 
    mongo_cde = require('../modules/cde/node-js/mongo-cde'), 
    async = require('async'); 

var mongoUrl = config.mongoUri; 
var conn = mongoose.createConnection(mongoUrl); 
var DataElement = conn.model('DataElement', cde_schemas.dataElementSchema); 
var Form = conn.model('Form', form_schemas.formSchema); 

var formCounter = 0; 

Form.find({ 
    archived: null 
}).exec(function (err, forms) { 
    if (err) { 
     console.log(err); 
     process.exit(0); 
    } 
    async.eachSeries(forms, function (form, doneOneForm) { 
     console.log("begin " + formCounter + " form id: " + form.tinyId); 
     var questionCount = 0; 
     var areYouDone = function() { 
      console.log(questionCount); 
      if (questionCount === 0) { 
       form.save(function (err) { 
        if (err) 
         process.exit(1); 
        else { 
         console.log('saved form id: ' + form.tinyId); 
         formCounter++; 
         doneOneForm(); 
        } 
       }); 
      } 
     }; 
     var formElements = form.formElements; 
     var getQuestions = function (formElements) { 
      formElements.forEach(function (fe) { 
       if (fe.elementType === 'question') { 
        questionCount++; 
        var cdeTinyId = fe.question.cde.tinyId; 
        var version = fe.question.cde.version; 
        DataElement.findOne({tinyId: cdeTinyId, version: version}).exec(function (err, cde) { 
         questionCount--; 
         if (err) { 
          console.log(err); 
          process.exit(0); 
         } 
         console.log('found cde id: ' + cdeTinyId + ' version: ' + version); 
         if (cde && cde.ids) fe.question.cde.ids = cde.ids; 
         //if I run this program with this comment instead of above, there is no error, but error happens on the ids which is array of string. 
         //fe.question.cde.name = cde.naming[0].designation; 
         else { 
          console.log("no CDE with id: " + cdeTinyId) 
         } 
         areYouDone(); 
        }); 
       } 
       else { 
        getQuestions(fe.formElements); 
       } 
      }); 
     }; 
     getQuestions(formElements); 
     areYouDone(); 
     form.markModified('formElements'); 
    }, function doneAllForms() { 
     console.log('finished all forms, # form: ' + formCounter); 
     process.exit(0); 
    }); 
}); 
+0

我通过在('data')上使用stream而不是async,stream.pause()来解决此问题。在form.save之后,stream.resume。 – sh977218

回答

0

没有看到任何从你的日志语句输出,我的猜测是你正在进入某种无限递归。您到目前为止显示的代码中可能的罪魁祸首是getQuestions(fe.formElements)一行。

formElements属性指的是它本身(或者以创建循环引用的类似方式引用另一个元素),并且可能第一个值是这样的,因此它只是一遍又一遍地调用该函数,而没有forEach()完成。

我想类似的事情也可能发生,如果没有循环引用,而是从一组formElements下一个链接足够长,造成的问题,并导致getQuestions()进行至少一次为每个forEach()执行。

您可能希望从较小的表单集合开始,并/或验证您的fe.elementType值和formElements链接/引用是他们应该做的。

相关问题