diff --git a/src/browser/BrowserPerRequestHashConcurrency.ts b/src/browser/BrowserPerRequestHashConcurrency.ts index daf7b789..d80e175c 100644 --- a/src/browser/BrowserPerRequestHashConcurrency.ts +++ b/src/browser/BrowserPerRequestHashConcurrency.ts @@ -139,11 +139,18 @@ type WorkerDeps = { class Worker implements WorkerInstance { private currentBrowser: puppeteer.Browser; private repairing = false; + private isClosed = false; private openInstances = 0; private waitingForRepairResolvers: Array<(val?: unknown) => void> = []; + private browserHealthCheckInterval: NodeJS.Timeout; constructor(private deps: WorkerDeps) { this.currentBrowser = deps.browser; + this.browserHealthCheckInterval = setInterval(() => { + if (!this.currentBrowser.isConnected()) { + this.close(); + } + }, 20000); } async repair() { @@ -163,6 +170,11 @@ class Worker implements WorkerInstance { this.deps.log.debug('Unable to close browser', 'jobHash', this.deps.jobHash, 'workerId', this.deps.id, 'err', err.stack); } + if (this.isClosed) { + this.deps.onShutdown(); + return; + } + try { this.currentBrowser = await this.deps.puppeteer.launch(this.deps.launchOptions); this.deps.log.debug('Worker finished repair', 'jobHash', this.deps.jobHash, 'workerId', this.deps.id); @@ -215,7 +227,14 @@ class Worker implements WorkerInstance { } async close(): Promise { + this.isClosed = true; + + clearInterval(this.browserHealthCheckInterval); await this.deps.onShutdown(); + + if (this.repairing) { + await this.repair(); + } this.deps.log.debug(`Closing worker`, 'jobHash', this.deps.jobHash, 'workerId', this.deps.id); await this.currentBrowser.close(); }