首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >快车主回路在密集操作中被阻塞

快车主回路在密集操作中被阻塞
EN

Stack Overflow用户
提问于 2022-07-18 10:53:15
回答 2查看 50关注 0票数 1

我正在运行一个高速公路服务器,在该服务器中,端点init执行一些紧张的操作,平均完成时间为10秒。在这10秒内,主循环被“卡住”,因此不可能将请求发送到高速公路服务器。我已经在googling上搜索了一段时间,但是没有发现任何能够同时处理请求的快捷方式。如果这不可能的话,那就太傻了。对于任何暗示或帮助,我都非常感激。

示例代码:

routes.js

代码语言:javascript
复制
app.route('/v1/cv/random').get(init);

特性/init.js

代码语言:javascript
复制
module.exports = async function init(req, res) {
    try {
        // perform some time consuming operation here
        res.status(201).send(someVar);
    } catch (err) {
        res.status(500).send(`failed to init`).end();
    }
};
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-07-18 12:55:45

可以以同步的方式实现长时间运行的算法,例如河内塔

代码语言:javascript
复制
function move(from, to, via, n) {
  if (n > 1)
    move(from, via, to, n - 1);
  to.unshift(from.shift());
  if (n > 1)
    move(via, to, from, n - 1);
}
app.get("/tower", function(req, res) {
  var a = [];
  for (var i = 0; i < Number(req.query.n); i++) a.push(i);
  var b = [];
  var c = [];
  move(a, b, c, a.length);
  res.end("Done");
});

使用足够大的GET /tower?n=<N>调用<N>确实会阻塞express的主循环。

可以通过在算法中引入异步性来避免这种阻塞,例如使用setTimeout(nextAlgorithmicStep)命令。这将nextAlgorithmicStep函数放入队列中,但同一队列也有处理并发请求的函数的空间:

代码语言:javascript
复制
function tick(from, to, via, n) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      move(from, to, via, n, resolve);
    });
  });
}
async function move(from, to, via, n, resolve) {
  if (n > 1)
    await tick(from, via, to, n - 1);
  to.unshift(from.shift());
  if (n > 1)
    await tick(via, to, from, n - 1);
  resolve();
}
app.get("/tower", async function(req, res) {
  var a = [];
  for (var i = 0; i < Number(req.query.n); i++) a.push(i);
  var b = [];
  var c = [];
  await tick(a, b, c, a.length);
  res.end("Done");
});

这样,您可以等待(永远)请求GET /tower?n=64回来,但至少仍然可以向同一台服务器发出并发请求。(使用简单的Promiseprocess.nextTick代替setTimeout并不能“异步”到允许在两者之间处理并发请求。)

然而,在第一个版本中“立即”完成的GET /tower?n=10的执行现在要花费更长的时间。最好不是在递归的所有setTimeout级别上使用setTimeout,而是只在大约十分之一的级别上使用。您必须在RSA算法中找到类似的异步性优点。

这就是使用单线程Node.js程序可以做的事情。但是有一种选择是使用多Node.js过程

代码语言:javascript
复制
app.get("/tower", function(req, res) {
  spawn("node", ["tower.js", req.query.n]).stdout.pipe(res);
});

其中tower.js是一个额外的Javascript程序:

代码语言:javascript
复制
function move(from, to, via, n) {
  if (n > 1)
    move(from, via, to, n - 1);
  to.unshift(from.shift());
  if (n > 1)
    move(via, to, from, n - 1);
}

var a = [];
for (var i = 0; i < Number(process.argv[2]); i++) a.push(i);
var b = [];
var c = [];
move(a, b, c, a.length);
process.stdout.write("Done");
票数 2
EN

Stack Overflow用户

发布于 2022-07-19 10:42:52

我在@Heiko en更新他的答案之前不久找到了一个答案。这(我认为)是一种类似的方法。

我找到了一种使用child_process的方法,通过使用

代码语言:javascript
复制
const {fork} = require('child_process');

...

module.exports = async function init(req, res) {
    try {
        const childProcess = fork('./path/to/the/script.js');

        childProcess.send({'body': req.body});
        childProcess.on('message', (message) => {
            res.status(201).json({someVar: message}).end();
        });
    } catch (err) {
        res.status(500).send(`failed to init`).end();
    }
};

script.js看起来就像

代码语言:javascript
复制
process.on('message', async (message) => {
    // perform a time consuming operation here
    process.send(someVar);
    process.exit();
});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73021181

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档