Bull js 阻止表达 api 请求直到作业完成

Bull js blocks express api requests until jobs finish

我有工作服务器 运行宁 Bull 和快递。

服务器要求

接收包含对象的请求并将该对象用作本地程序的输入(别无选择),这需要几分钟到几个小时才能完成 运行。作业 必须 是 运行 一个接一个,顺序是它们收到的顺序(没有办法绕过这个)。

TL;DR 服务器:

// Set up Bull queue and process
const osmQueue = new Bull("osm", {
    redis: {
        port: "6969",
    },
});
osmQueue.process((job) => {
    extractOms(job);
});

// Process function
const extractOms = (job) => {
    // I have tried execSync also
    spawnSync("programme", [
        "this",
        "programme",
        "takes",
        "~30",
        "minutes",
        "to",
        "run",
        "and",
        "requires",
        "full",
        "system",
        "resources (cannot share system resources with another job)",
    ]);

return
};

// Express server with single route
const app = express();
app.post("/create-map-job", (req, res) => {
    console.log("fired"); // Fires on first request. Blocked on second until job done
    osmQueue.add(req.body);
    res.send("job successfully queued"); // Returns on first request. Blocked on second until job done
});

app.listen(PORT, () => {
    console.log(`Listening on ${PORT}`);
});

问题:

  1. 当我向这条路线发送数据时,一切都按预期进行。作业开始,我从服务器收到 'job successfully queued'。
  2. 当我第二次向服务器发送数据时(之前的作业还在运行ning),路由中的console.log没有开火,请求挂起,直到现有作业完成。现有作业完成后,请求将被确认,下一个作业将排队。

我尝试过的事情:

  1. 使用 spawn() 而不是 spawnSync()。虽然这意味着请求不再被阻塞,但它意味着所有作业都在同一时间执行。我已经研究了 Bull 的并发性,但是当 child_process 像 spawn() 或 exec() 这样的异步时,一旦程序成功启动,作业就会被标记为完成——它不会等待 spawn() 完成.这意味着服务器认为该作业已完成并愉快地加载到另一个作业中,我 运行 内存很快就用完了,系统崩溃了。 我根本无法限制或控制内存使用..如果有的话我需要为每个进程提供更多内存,所以我一次只能有 1 运行ning

  2. 在 osmQueue.add() 之前简单调用 res.send()。这对行为没有改变。

  3. 在队列上使用限制器:{max, duration} 选项。如果我将限制器持续时间设置为 5 小时,这会起作用,但这会大大减少我一次可以完成的工作量,达到无法接受的低水平。

  4. 我已经阅读并搜索了很长时间,但我找不到与我的类似的问题。

问题:

  1. 为什么系统进程在执行 res.send() 后会阻塞 node/express?
  2. 我应该使用另一个库吗?
  3. 非常感谢来自知情人士的任何见解。

让我知道是否还有其他我可以添加的内容,我会尽快添加。

TL;DR 要求:

作为作业的一部分执行系统进程,按顺序一个接一个地执行,而不会阻止服务器在现有作业 运行ning 时排队更多作业或响应请求.

已解决;令人惊奇的是,完整地写出一个问题可以激发大脑并让你重新审视事物。留在这里供未来的 Google 员工使用。

从 Bull 文档中查看 > https://github.com/OptimalBits/bull#separate-processes

我需要调用 Bull 的独立进程。这允许我 运行 在与 node/express 进程分开的进程中阻止代码,这意味着未来的请求不会被阻止,即使同步代码是 运行ning.

// osm.processor.js
module.exports = extractOms (job) {
    spawnSync("programme", [
        "this",
        "programme",
        "takes",
        "~30",
        "minutes",
        "to",
        "run",
        "and",
        "requires",
        "full",
        "system",
        "resources (cannot share system resources with another job)",
    ]);
    return;
}
// queue.js
osmQueue.process(
    "/path/to/file/above/job-server/processors/osm.processor.js"
);

这会在单独的进程中产生阻塞工作。谢谢公牛!