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}`);
});
问题:
- 当我向这条路线发送数据时,一切都按预期进行。作业开始,我从服务器收到 'job successfully queued'。
- 当我第二次向服务器发送数据时(之前的作业还在运行ning),路由中的console.log没有开火,请求挂起,直到现有作业完成。现有作业完成后,请求将被确认,下一个作业将排队。
我尝试过的事情:
使用 spawn() 而不是 spawnSync()。虽然这意味着请求不再被阻塞,但它意味着所有作业都在同一时间执行。我已经研究了 Bull 的并发性,但是当 child_process 像 spawn() 或 exec() 这样的异步时,一旦程序成功启动,作业就会被标记为完成——它不会等待 spawn() 完成.这意味着服务器认为该作业已完成并愉快地加载到另一个作业中,我 运行 内存很快就用完了,系统崩溃了。 我根本无法限制或控制内存使用..如果有的话我需要为每个进程提供更多内存,所以我一次只能有 1 运行ning
在 osmQueue.add() 之前简单调用 res.send()。这对行为没有改变。
在队列上使用限制器:{max, duration} 选项。如果我将限制器持续时间设置为 5 小时,这会起作用,但这会大大减少我一次可以完成的工作量,达到无法接受的低水平。
我已经阅读并搜索了很长时间,但我找不到与我的类似的问题。
问题:
- 为什么系统进程在执行 res.send() 后会阻塞 node/express?
- 我应该使用另一个库吗?
- 非常感谢来自知情人士的任何见解。
让我知道是否还有其他我可以添加的内容,我会尽快添加。
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"
);
这会在单独的进程中产生阻塞工作。谢谢公牛!
我有工作服务器 运行宁 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}`);
});
问题:
- 当我向这条路线发送数据时,一切都按预期进行。作业开始,我从服务器收到 'job successfully queued'。
- 当我第二次向服务器发送数据时(之前的作业还在运行ning),路由中的console.log没有开火,请求挂起,直到现有作业完成。现有作业完成后,请求将被确认,下一个作业将排队。
我尝试过的事情:
使用 spawn() 而不是 spawnSync()。虽然这意味着请求不再被阻塞,但它意味着所有作业都在同一时间执行。我已经研究了 Bull 的并发性,但是当 child_process 像 spawn() 或 exec() 这样的异步时,一旦程序成功启动,作业就会被标记为完成——它不会等待 spawn() 完成.这意味着服务器认为该作业已完成并愉快地加载到另一个作业中,我 运行 内存很快就用完了,系统崩溃了。 我根本无法限制或控制内存使用..如果有的话我需要为每个进程提供更多内存,所以我一次只能有 1 运行ning
在 osmQueue.add() 之前简单调用 res.send()。这对行为没有改变。
在队列上使用限制器:{max, duration} 选项。如果我将限制器持续时间设置为 5 小时,这会起作用,但这会大大减少我一次可以完成的工作量,达到无法接受的低水平。
我已经阅读并搜索了很长时间,但我找不到与我的类似的问题。
问题:
- 为什么系统进程在执行 res.send() 后会阻塞 node/express?
- 我应该使用另一个库吗?
- 非常感谢来自知情人士的任何见解。
让我知道是否还有其他我可以添加的内容,我会尽快添加。
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"
);
这会在单独的进程中产生阻塞工作。谢谢公牛!