diff --git a/src/server/index.spec.ts b/src/server/index.spec.ts index 62a6563d..ce38d963 100644 --- a/src/server/index.spec.ts +++ b/src/server/index.spec.ts @@ -93,7 +93,7 @@ describe('withServer', () => { const browser = await getBrowser() defer(() => browser.close()) - const server = await createServer({ browser, port }) + const server = await createServer({ getBrowserFn: () => browser, port }) defer(() => server.close()) const res: IncomingMessage = await new Promise((resolve) => { @@ -137,7 +137,7 @@ describe('withServer', () => { const browser = await getBrowser() defer(() => browser.close()) - const server = await createServer({ browser, port }) + const server = await createServer({ getBrowserFn: () => browser, port }) defer(() => server.close()) const res: IncomingMessage = await new Promise((resolve) => { @@ -153,7 +153,7 @@ describe('withServer', () => { it('returns 502 when browser becomes unavailable', async () => { const port = 8093 const browser = await getBrowser() - const server = await createServer({ browser, port }) + const server = await createServer({ getBrowserFn: () => browser, port }) try { await browser.close() @@ -178,7 +178,7 @@ describe('withServer', () => { const browser = await getBrowser() defer(() => browser.close()) - const server = await createServer({ browser, port }) + const server = await createServer({ getBrowserFn: () => browser, port }) defer(() => server.close()) const res: IncomingMessage = await new Promise((resolve) => { @@ -199,7 +199,7 @@ describe('withServer', () => { defer(() => browser.close()) const server = await createServer({ - browser, + getBrowserFn: () => browser, port, maxConcurrentRenders: 0, }) @@ -222,7 +222,7 @@ describe('withServer', () => { defer(() => browser.close()) const server = await createServer({ - browser, + getBrowserFn: () => browser, port, maxConcurrentRenders: 0, }) @@ -245,7 +245,7 @@ describe('withServer', () => { defer(() => browser.close()) const server = await createServer({ - browser, + getBrowserFn: () => browser, port, maxConcurrentRenders: 0, }) diff --git a/src/server/index.ts b/src/server/index.ts index 0bae280d..a4c2fc77 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -126,7 +126,7 @@ function replyWithBadGateway(res: http.ServerResponse): void { } async function renderWithConcurrencyLimit( - browser: Browser, + getBrowserFn: () => Browser, req: http.IncomingMessage, res: http.ServerResponse, counter: { value: number }, @@ -139,18 +139,17 @@ async function renderWithConcurrencyLimit( } counter.value++ try { - await respondToIncomingRequest(browser, req, res) + await respondToIncomingRequest(getBrowserFn(), req, res) } finally { counter.value-- } } export function createHandler( - browser: Browser, + getBrowserFn: () => Browser, { maxConcurrentRenders = 10 }: { maxConcurrentRenders?: number } = {}, ) { const counter = { value: 0 } - return function renderHandler( req: http.IncomingMessage, res: http.ServerResponse, @@ -159,28 +158,28 @@ export function createHandler( const task = parsedRequest.type === 'render' ? renderWithConcurrencyLimit( - browser, + getBrowserFn, req, res, counter, maxConcurrentRenders, ) - : respondToIncomingRequest(browser, req, res) + : respondToIncomingRequest(getBrowserFn(), req, res) task.catch(() => replyWithBadGateway(res)) } } export async function createServer({ - browser, + getBrowserFn, port = 8080, maxConcurrentRenders = 10, }: { - browser: Browser + getBrowserFn: () => Browser port: number maxConcurrentRenders?: number }): Promise { const server = http.createServer( - createHandler(browser, { maxConcurrentRenders }), + createHandler(getBrowserFn, { maxConcurrentRenders }), ) await new Promise((resolve) => { server.listen(port, () => { @@ -225,10 +224,28 @@ export async function main({ maxConcurrentRenders = 10, }: ServerArgument = {}): Promise { await runWithDefer(async (defer) => { - const browser = await getBrowser({ name, headless }) - defer(() => browser.close()) + let activeBrowser = await getBrowser({ name, headless }) + + const onDisconnected = async () => { + try { + activeBrowser = await getBrowser({ name, headless }) + activeBrowser.on('disconnected', onDisconnected) + } catch { + // Restart failed; subsequent requests will error naturally + } + } + activeBrowser.on('disconnected', onDisconnected) + + defer(async () => { + activeBrowser.removeListener('disconnected', onDisconnected) + await activeBrowser.close() + }) - const server = await createServer({ browser, port, maxConcurrentRenders }) + const server = await createServer({ + getBrowserFn: () => activeBrowser, + port, + maxConcurrentRenders, + }) defer(() => closeServerGracefully(server)) await waitForProcessExit()