puppeteer-cluster:设置单个执行任务的超时

时间:2019-08-07 12:32:30

标签: javascript node.js puppeteer-cluster

我正在尝试让单个任务在压力测试过程中超时,以查看我的调用程序将要执行的操作。但是,我的集群无限期地使任务保持最新状态。它似乎将我所有的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;
    } 
};

1 个答案:

答案 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个作业,并按顺序运行它们(因为maxConcurrency1)。这里的queueexecute之间没有什么区别(有关此主题的更多信息,请参见this question)。因此,发生了以下情况:

  • 第一个作业开始运行
  • 一秒钟后第一项工作中断了
  • 第二个作业开始运行
  • 第二个工作在一秒钟后中断
  • ...

该库当前不支持您正在描述的用例(顺便说一句,免责声明:我是作者),但是按照您的建议,您可以向要排队的对象添加时间戳,并立即取消作业如果过去太远了。