我正在尝试让单个任务在压力测试过程中超时,以查看我的调用程序将要执行的操作。但是,我的集群无限期地使任务保持最新状态。它似乎将我所有的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)的澄清,我决定构建此小优化程序,以防止执行长时间监听程序的任务。
仅将html和data
的内容交换为同时包含url和时间戳的json:
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;
}
};
答案 0 :(得分:2)
这是对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)。因此,发生了以下情况:
该库当前不支持您正在描述的用例(顺便说一句,免责声明:我是作者),但是按照您的建议,您可以向要排队的对象添加时间戳,并立即取消作业如果过去太远了。