我正在尝试让个别任务在压力测试期间暂停,以查看我的调用程序将执行的操作。但是,我的集群会无限期地保持任务新鲜。它似乎在排队我所有的 cluster.execute
然后将这些调用保存在内存中并将其结果返回给早已断开连接的监听器。
文档状态:
timeout <number> Specify a timeout for all tasks. Defaults to 30000 (30 seconds).
我的集群启动配置:
const cluster = await Cluster.launch({
concurrency: Cluster.CONCURRENCY_CONTEXT,
maxConcurrency: 1,
timeout: 1000 //milliseconds
});
我调用排队机制使用:
const pdf = await cluster.execute(html, makePdf);
其中 makePdf 是 async
需要 HTML 字符串的函数,用它填充页面并使用默认值 puppeteer
打印 PDF .
const makePdf = async ({ page, data: html, worker }) => {
await page.setContent(html);
let pdf = await page.pdf({});
console.log('worker ' + worker.id + ' task ' + count);
return pdf;
};
我有点希望队列开始自行清空,直到它找到一个没有超过其超时值的任务。我试过设置 timeout
到 1 毫秒,但这也不会触发超时。我试过将此代码移动到 cluster.task
如示例中所述,看看是否会触发设置,但没有这样的运气。如何让已经排队的请求超时?如果我不抓取网站或连接任何东西,这是否有效?
我正在考虑将时间戳与我的任务一起传递,这样它就可以跳过对调用方已过期的请求执行任何操作,但我宁愿尽可能使用内置选项。
编辑:
感谢 Thomas 的澄清,我决定构建这个小优化,以防止执行监听器早已消失的任务。
交换data
的内容来自带有 url 和时间戳的 json 的 html:
let timestamp = new Date();
await cluster.execute({html, timestamp});
忽略监听器超时的任何排队任务:
const makePdf = async ({ page, data: { html, timestamp }, worker }) => {
let time_since_call = (new Date() - timestamp);
if (time_since_call < timeout_ms) {
await page.setContent(html);
let pdf = await page.pdf({});
return pdf;
}
};
最佳答案
这是对 timeout
作用的误解。 timeout
选项是任务的超时时间,这意味着作业本身(离开队列后)不能超过指定的超时时间。该选项不会取消仍在队列中的排队作业。
示例:
const cluster = await Cluster.launch({
// ...
maxConcurrency: 1,
timeout: 1000 // one second
});
// ...
for (let i = 0; i < 10; i += 1) {
cluster.queue('...');
}
此代码添加 10 个作业并按顺序运行它们(因为 maxConcurrency
是 1
)。这里的 queue
和 execute
没有区别(有关此主题的更多信息,请参阅 this question)。那么会发生以下情况:
- 第一个作业开始运行
- 第一个作业在一秒钟后中断
- 第二个作业开始运行
- 第二个作业在一秒钟后中断
- ...
库目前不支持您描述的用例(顺便说一句,免责声明:我是作者),但正如您所建议的,您可以向正在排队的对象添加时间戳并立即取消作业如果过去太远。
关于javascript - puppeteer-cluster:为单个执行任务设置超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57394609/