如何使用 Bull.js 队列 return 生成图像?

How to return a generated image with Bull.js queue?

我的用例是这样的:我想创建页面部分内容的屏幕截图。由于技术原因,它不能在客户端完成(参见下面的相关问题),但需要在服务器上使用 puppeteer。

因为我是 运行 Heroku 上的这个,所以我有一个非常小的超时的额外限制 window。因此,Heroku 建议实现基于 bull.js 的排队系统,并使用 worker 进程处理更长的 运行 任务,如 explained here.

我有两个端点(使用 Express 实现),一个接收 POST 具有某种配置的请求 JSON,另一个在提供作业标识符时响应 GET(稍作修改为简洁起见):

这会将作业添加到队列中:

router.post('/', async function(req, res, next) {
    let job = await workQueue.add(req.body.chartConfig)
    res.json({ id: job.id })
})

这份return关于工作的信息

router.get('/:id', async(req, res) => {
    let id = req.params.id;
    let job = await workQueue.getJob(id);
    
    let state = await job.getState();
    let progress = job._progress;
    let reason = job.failedReason;
    res.json({ id, state, progress, reason });
})

在不同的文件中:

const start = () => {
    let workQueue = new queue('work', REDIS_URL);
    workQueue.process(maxJobsPerWorker, getPNG)
}

const getPNG = async(job) => {

    const { url, width, height, chart: chartConfig, chartUrl } = job.data

    // ... snipped for brevity

    const png = await page.screenshot({
        type: 'png',
        fullPage: true
    })
    await page.close()
    job.progress(100)
    return Promise.resolve({ png })
}

// ...

throng({ count: workers, worker: start })

module.exports.getPNG = getPNG

末尾的 throng 调用将 start 函数指定为从队列中选择作业时要调用的辅助函数。 start 本身指定 getPNG 在处理作业时调用。

我现在的问题是:如何获取生成的图像(png)?我想理想情况下我希望能够调用上面的 GET 端点 return 图像,但我不知道如何传递图像对象。

作为更复杂的回退解决方案,我可以想象将图像发布到像 imgur 这样的图像托管服务,然后根据 GET 端点的请求 returning URL。但如果可能的话,我更愿意让事情简单化。

这个问题是这个问题的后续问题:

我打开了一个 ticket on the GitHub repository of the bull 项目。开发人员表示,首选做法 是将二进制对象存储在其他地方,并且仅将 link 元数据添加到作业的数据存储中。

但是,他们还说作业对象的存储限制似乎是 512 Mb。所以也很有可能将一个合理大小的图像存储为base64编码的字符串。