我看到其他人在运行Firebase Function时遇到了相对较小的性能问题。在我的情况下,Firebase在我可以用木偶师做任何事情之前就超时了,即使内存和超时秒数一直在增加。
代码:
import * as functions from "firebase-functions";
import puppeteer from "puppeteer";
const runScreenshot = async () => {
console.log("Launching puppeteer...");
console.time("launch");
const browser = await puppeteer.launch();
console.timeEnd("launch");
console.log("Awaiting browser.newPage()...");
console.time("newPage");
const page = await browser.newPage();
console.timeEnd("newPage");
console.log("Setting viewport...");
console.time("setViewport");
page.setViewport({ width: 2000, height: 4000, deviceScaleFactor: 4 });
console.timeEnd("setViewport");
console.log("Goto page...");
console.time("goto");
await page.goto(
"https://public.tableau.com/views/NCDHHS_COVID-19_Dashboard_Summary/NCDHHS_DASHBOARD_SUMMARY"
);
console.timeEnd("goto");
console.log("Waiting for selector...");
console.time("selector");
await page.waitForSelector("#tab-dashboard-region");
console.timeEnd("selector");
// Wait for the spinner to go away
await new Promise((r) => setTimeout(r, 100));
console.time("href");
const href = await page.$("#tab-dashboard-region");
console.timeEnd("href");
console.time("screenshot");
href && (await href.screenshot({ path: "tmp/test.png" }));
console.timeEnd("screenshot");
return browser.close();
};
export const screenshot = functions
.runWith({ memory: "2GB", timeoutSeconds: 540 })
.pubsub.schedule("44 21 * * *")
.timeZone("America/New_York")
.onRun(() => {
return runScreenshot();
});
以下是生成的Firebase函数日志。运行puppeteer.launch()
需要几秒钟,然后browser.newPage()
在超时前的8分钟内根本无法完成。
9:44:04.012 PM
screenshot
Function execution started
9:44:04.555 PM
screenshot
Launching puppeteer...
9:44:09.427 PM
screenshot
launch: 4870.195ms
9:44:09.427 PM
screenshot
Awaiting browser.newPage()...
9:53:04.014 PM
screenshot
Function execution took 540004 ms, finished with status: 'timeout'
完整的可复制示例:https://github.com/danbockapps/firebase-puppeteer
我通过将{args: [ '--no-sandbox', '--disable-setuid-sandbox']}
添加到puppeteer.launch来修复此问题,如下所示:https://github.com/puppeteer/puppeteer/issues/6568
传递给onRun的函数不会返回任何内容。在这种情况下,它几乎会立即终止,几乎不会发生其他事情。异步工作不能保证完成。
相反,您应该做的是返回promise,该promise仅在所有异步工作完成后才重新存储。由于downloadScreenshot
本身返回一个promise,您可以直接返回它:
export const screenshot = functions
.runWith({ memory: '2GB', timeoutSeconds: 540 })
.pubsub.schedule('27 16 * * *')
.timeZone('America/New_York')
.onRun(() => { return downloadScreenshot('tmp/downloaded_image.png') })
有关详细信息,请参阅文档。