Skip to content

Commit

Permalink
Restart browser if killed on Mermaid
Browse files Browse the repository at this point in the history
  • Loading branch information
ggrossetie committed May 4, 2024
1 parent 5bb986a commit 654beba
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 11 deletions.
18 changes: 14 additions & 4 deletions mermaid/src/browser-instance.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import puppeteer from 'puppeteer'

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

let INSTANCE;

const createBrowser = async () => {
const browser = await puppeteer.launch({
headless: 'new',
Expand Down Expand Up @@ -30,8 +32,9 @@ const createBrowser = async () => {
'--disable-software-rasterizer'
]
})

const browserProcess = browser.process()
logger.info(`Chrome instance launched with pid ${browserProcess.pid}`)

browserProcess.stdout.unpipe()
browserProcess.stderr.unpipe()
browserProcess.stdout.on('data', (data) => {
Expand All @@ -50,6 +53,9 @@ const createBrowser = async () => {
})
browserProcess.on('exit', (code, signal) => {
logger.error({ code, signal }, 'chrome process exited')
browserProcess.kill()
browser.close();
INSTANCE = undefined;
})
browserProcess.on('message', (message) => {
logger.warn({ message }, 'chrome process message')
Expand All @@ -60,10 +66,14 @@ const createBrowser = async () => {
await browser.close()
throw err
} finally {
browser.disconnect()
await browser.disconnect()
}
}

export async function create () {
return createBrowser()
export async function getBrowserWSEndpoint () {
if (INSTANCE === undefined) {
INSTANCE = await createBrowser()
logger.info(`Chrome accepting connections on endpoint ${INSTANCE.wsEndpoint()}`)
}
return INSTANCE.wsEndpoint();
}
5 changes: 1 addition & 4 deletions mermaid/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@ import http from 'node:http'
import micro from 'micro'
import { SyntaxError, TimeoutError, Worker } from './worker.js'
import Task from './task.js'
import { create } from './browser-instance.js'

(async () => {
// QUESTION: should we create a pool of Chrome instances ?
const browser = await create()
logger.info(`Chrome accepting connections on endpoint ${browser.wsEndpoint()}`)
const worker = new Worker(browser)
const worker = new Worker()
const server = new http.Server(
micro.serve(async (req, res) => {
// Add a /health route that renders a sample diagram by calling the worker
Expand Down
7 changes: 4 additions & 3 deletions mermaid/src/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import path from 'node:path'
import puppeteer, { HTTPResponse, Page } from 'puppeteer'
import { logger } from './logger.js'
import { updateConfig } from './config.js'
import { getBrowserWSEndpoint } from './browser-instance.js'

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

Expand All @@ -22,8 +23,7 @@ export class SyntaxError extends Error {
}

export class Worker {
constructor (browserInstance) {
this.browserWSEndpoint = browserInstance.wsEndpoint()
constructor () {
this.pageUrl = process.env.KROKI_MERMAID_PAGE_URL || `file://${path.join(__dirname, '..', 'assets', 'index.html')}`
this.convertTimeout = process.env.KROKI_MERMAID_CONVERT_TIMEOUT || '10000'
}
Expand Down Expand Up @@ -109,8 +109,9 @@ export class Worker {
* @private
*/
async _connect () {
const browserWSEndpoint = await getBrowserWSEndpoint()
return await puppeteer.connect({
browserWSEndpoint: this.browserWSEndpoint,
browserWSEndpoint,
ignoreHTTPSErrors: true
})
}
Expand Down

0 comments on commit 654beba

Please sign in to comment.