1

我试图让个别任务在压力测试期间超时,看看我的调用程序会做什么。但是,我的集群可以无限期地保持任务新鲜。它似乎将我所有的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.

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示例中所述的 a 以查看是否会触发设置,但没有这样的运气。如何让已经排队的请求超时?如果我不抓取网站或连接到任何东西,这是否有效?

我正在考虑将时间戳与我的任务一起传递,以便它可以跳过对调用方已过期的请求执行任何操作,但我宁愿尽可能使用内置选项。

编辑:

感谢 Thomas 的澄清,我决定构建这个小优化,以防止侦听器长期执行的任务。

data将html 的内容与包含 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;
    } 
};
4

1 回答 1

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 个作业并按顺序运行它们(原样maxConcurrency1queueexecute此处没有区别(有关此主题的更多信息,请参阅此问题)。所以会发生以下情况:

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

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

于 2019-08-07T17:19:25.440 回答