Files
Quote-Generator/browserPool.js

110 lines
2.4 KiB
JavaScript

const puppeteer = require('puppeteer');
const POOL_SIZE = parseInt(process.env.BROWSER_POOL_SIZE) || 5;
const VIEWPORT_WIDTH = 3240;
const VIEWPORT_HEIGHT = 3240;
let browsers = [];
let availableBrowsers = [];
let initPromise = null;
async function initPool() {
if (initPromise) return initPromise;
initPromise = (async () => {
console.log(`Initializing browser pool with ${POOL_SIZE} instances...`);
for (let i = 0; i < POOL_SIZE; i++) {
const browser = await puppeteer.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
browsers.push(browser);
availableBrowsers.push(browser);
}
console.log(`Browser pool ready with ${POOL_SIZE} browsers`);
})();
return initPromise;
}
async function acquireBrowser() {
await initPool();
// wait for available browser
while (availableBrowsers.length === 0) {
await new Promise(resolve => setTimeout(resolve, 50));
}
return availableBrowsers.pop();
}
function releaseBrowser(browser) {
availableBrowsers.push(browser);
}
// renders html and returns screenshot as buffer
async function renderHtml(html, waitTime = 1000) {
const browser = await acquireBrowser();
let page = null;
try {
page = await browser.newPage();
await page.setViewport({
width: VIEWPORT_WIDTH,
height: VIEWPORT_HEIGHT
});
await page.setContent(html, { waitUntil: 'networkidle0' });
// wait for any animations or laoding
await new Promise(resolve => setTimeout(resolve, waitTime));
const screenshot = await page.screenshot({
type: 'png',
fullPage: false
});
return screenshot;
} finally {
if (page) await page.close();
releaseBrowser(browser);
}
}
async function shutdownPool() {
console.log('Shutting down browser pool...');
for (const browser of browsers) {
await browser.close();
}
browsers = [];
availableBrowsers = [];
initPromise = null;
console.log('Browser pool shut down');
}
// Graceful shutdown handlers
process.on('SIGINT', async () => {
await shutdownPool();
process.exit(0);
});
process.on('SIGTERM', async () => {
await shutdownPool();
process.exit(0);
});
module.exports = {
initPool,
renderHtml,
shutdownPool,
POOL_SIZE
};