nodejs使用mongoose错误:致命错误:CALL_AND_RETRY_LAST分配失败 - 进程内存不足

时间:2016-01-28 23:11:09

标签: node.js mongodb mongoose

我有一个nodejs程序只是将一个字段从一个集合复制到另一个集合。我写了两篇。一个副本字段命名(字符串),另一个副本ID(字符串数组)。集合不大,大约只有900种形式需要迭代。我可以看到它运行并保存了一些表单,但我不明白为什么在程序继续运行时出现这个错误:

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);
    });
});

1 个答案:

答案 0 :(得分:0)

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

formElements属性引用自身(或者以类似的方式引用另一个元素来创建循环引用),并且第一个值可能是fe.elementType !== 'question'所以它只是继续调用函数一遍又一遍,forEach()都没有完成。

我想如果没有循环引用也会发生类似的事情,但是从formElements到下一组getQuestions()的链接长到足以导致问题并导致forEach()至少被执行每次fe.elementType一次。

您可能希望从较小的表单集开始和/或验证您的formElements值和JSON.stringify链接/引用是否应该是它们。