Skip to content

Commit 70f251a

Browse files
committed
Restart browser if killed on Mermaid
1 parent 399b4ba commit 70f251a

File tree

3 files changed

+19
-11
lines changed

3 files changed

+19
-11
lines changed

Diff for: mermaid/src/browser-instance.js

+14-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import puppeteer from 'puppeteer'
22

33
import { logger } from './logger.js'
44

5+
let INSTANCE
6+
57
const createBrowser = async () => {
68
const browser = await puppeteer.launch({
79
headless: 'new',
@@ -30,8 +32,9 @@ const createBrowser = async () => {
3032
'--disable-software-rasterizer'
3133
]
3234
})
33-
3435
const browserProcess = browser.process()
36+
logger.info(`Chrome instance launched with pid ${browserProcess.pid}`)
37+
3538
browserProcess.stdout.unpipe()
3639
browserProcess.stderr.unpipe()
3740
browserProcess.stdout.on('data', (data) => {
@@ -50,6 +53,9 @@ const createBrowser = async () => {
5053
})
5154
browserProcess.on('exit', (code, signal) => {
5255
logger.error({ code, signal }, 'chrome process exited')
56+
browserProcess.kill()
57+
browser.close()
58+
INSTANCE = undefined
5359
})
5460
browserProcess.on('message', (message) => {
5561
logger.warn({ message }, 'chrome process message')
@@ -60,10 +66,14 @@ const createBrowser = async () => {
6066
await browser.close()
6167
throw err
6268
} finally {
63-
browser.disconnect()
69+
await browser.disconnect()
6470
}
6571
}
6672

67-
export async function create () {
68-
return createBrowser()
73+
export async function getBrowserWSEndpoint () {
74+
if (INSTANCE === undefined) {
75+
INSTANCE = await createBrowser()
76+
logger.info(`Chrome accepting connections on endpoint ${INSTANCE.wsEndpoint()}`)
77+
}
78+
return INSTANCE.wsEndpoint()
6979
}

Diff for: mermaid/src/index.js

+1-4
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,10 @@ import http from 'node:http'
55
import micro from 'micro'
66
import { SyntaxError, TimeoutError, Worker } from './worker.js'
77
import Task from './task.js'
8-
import { create } from './browser-instance.js'
98

109
(async () => {
1110
// QUESTION: should we create a pool of Chrome instances ?
12-
const browser = await create()
13-
logger.info(`Chrome accepting connections on endpoint ${browser.wsEndpoint()}`)
14-
const worker = new Worker(browser)
11+
const worker = new Worker()
1512
const server = new http.Server(
1613
micro.serve(async (req, res) => {
1714
// Add a /health route that renders a sample diagram by calling the worker

Diff for: mermaid/src/worker.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import path from 'node:path'
44
import puppeteer, { HTTPResponse, Page } from 'puppeteer'
55
import { logger } from './logger.js'
66
import { updateConfig } from './config.js'
7+
import { getBrowserWSEndpoint } from './browser-instance.js'
78

89
const __dirname = fileURLToPath(new URL('.', import.meta.url))
910

@@ -22,8 +23,7 @@ export class SyntaxError extends Error {
2223
}
2324

2425
export class Worker {
25-
constructor (browserInstance) {
26-
this.browserWSEndpoint = browserInstance.wsEndpoint()
26+
constructor () {
2727
this.pageUrl = process.env.KROKI_MERMAID_PAGE_URL || `file://${path.join(__dirname, '..', 'assets', 'index.html')}`
2828
this.convertTimeout = process.env.KROKI_MERMAID_CONVERT_TIMEOUT || '10000'
2929
}
@@ -109,8 +109,9 @@ export class Worker {
109109
* @private
110110
*/
111111
async _connect () {
112+
const browserWSEndpoint = await getBrowserWSEndpoint()
112113
return await puppeteer.connect({
113-
browserWSEndpoint: this.browserWSEndpoint,
114+
browserWSEndpoint,
114115
ignoreHTTPSErrors: true
115116
})
116117
}

0 commit comments

Comments
 (0)