【问题标题】:Function fails to fully build JSON under load函数无法在负载下完全构建 JSON
【发布时间】:2022-02-14 23:13:47
【问题描述】:

我正在开发一个名为 pSConfig Web Admin (PWA) 的 OSS 项目。我们遇到的最大问题是在负载下,生成的 JSON 有时会交付不完整(如 this issue 中所述)。

当它失败时,它似乎总是以同样的方式失败。即,groups 对象在应该包含更多项时只包含一项。例如,而不是得到这个:

{
  "archives": { … },
  "addresses": { … },
  "groups": {
    "Group 1": { … },
    "Group 2": { … },
    "Group 3": { … },
    "Group 4": { … }
  },
  "tests": { … },
  "schedules": { … },
  "tasks": { … },
  "_meta": { … },
  "hosts": { … }
}

我们会得到这个:

{
  "archives": { … },
  "addresses": { … },
  "groups": {
    "Group 4": { … }
  },
  "tests": { … },
  "schedules": { … },
  "tasks": { … },
  "_meta": { … },
  "hosts": { … }
}

我认为问题在于,一些异步调用在它们真正应该返回之前就返回了,我担心Zalgo has been unleashed,因为它不会一直发生。我怀疑问题出在exports._process_published_config function。即它如何在async.eachSeries 中使用async.parallel(但这只是我的猜测):

exports._process_published_config = function (_config, opts, cb) {
    …

    async.eachSeries(
        _config.tests,
        function (test, next_test) {
            var type = test.mesh_type;

            if (!test.enabled) return next_test();
            async.parallel(
                [
                    function (next) {
                        //a group
                        if (!test.agroup) return next();
                        generate_group_members(
                            test,
                            test.agroup,
                            test_service_types,
                            type,
                            next,
                            "a-"
                        );
                    },
                    function (next) {
                        //b group
                        if (!test.bgroup) return next();
                        generate_group_members(
                            test,
                            test.bgroup,
                            test_service_types,
                            type,
                            next,
                            "b-"
                        );
                    },
                    function (next) {
                        if (!test.nahosts) return next();
                        resolve_hosts(test.nahosts, function (err, hosts) {
                            if (err) return next(err);
                            test.nahosts = hosts;
                            hosts.forEach(function (host) {
                                host_catalog[host._id] = host;
                            });
                            next();
                        });
                    },
                    function (next) {
                        //testspec
                        if (!test.testspec) return next();

                        resolve_testspec(test.testspec, function (err, row) {
                            if (err) return next(err);
                            test.testspec = row;

                            //suppress testspecs that does't meet min host version
                            if (!_config._host_version) return next();
                            var hostv = parseInt(_config._host_version[0]);
                            var minver =
                                config.meshconfig.minver[test.service_type];
                            for (var k in test.testspec.specs) {
                                //if minver is set for this testspec, make sure host version meets it
                                if (minver && k in minver) {
                                    if (hostv < minver[k])
                                        delete test.testspec.specs[k];
                                }
                            }
                            next();
                        });
                    },
                ],
                next_test
            );
        },
        function (err) {
            …
        }
    );
};

有没有人以前见过类似的东西,或者在这段代码中看到过完全错误的东西?

我正试图通过使用 promises 和 async/await 重写其中的一部分来摆脱 回调地狱,但我不完全确定这会解决这个问题。无论如何,由于回调嵌套如此之深,重写是非常困难的。

【问题讨论】:

  • On Errors you do simple return next(err) 你是否将这个错误记录到任何地方(你也使用return next() 某些函数没有返回任何内容 - 你还应该检查是否没有或有那里的错误-也许这就是为什么您没有获得完整数据的原因((例如,在加载时,某些事情超时,然后您忽略它们而不是重试或返回错误))
  • 也可能是由于async.parallel 的工作方式,一些东西被正确返回,然后一个错误,然后所有其他东西都被停止 - 因为这个paralell 在错误发生后停止执行?

标签: javascript node.js async.js


【解决方案1】:

generate_group_members 很可能首先检查“组”数组是否为空,然后进行一些异步调用,然后将“组”初始化为 [] 并在那里推送一些东西。因此,generate_group_members 的两个并行调用可以找到“groups”为空,然后将其初始化为 []。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-03
    • 2016-04-02
    • 2018-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多