后端迁移会话运行时模块

This commit is contained in:
yml
2026-05-21 15:26:35 +08:00
parent 4453f17678
commit b86d7e8974
3 changed files with 53 additions and 20 deletions
@@ -0,0 +1,102 @@
import { chromium } from 'playwright'
import { runtimeConfig } from '../../config/runtime.js'
import {
buildChromiumLaunchOptions as buildChromiumLaunchOptionsBase,
resolveBrowserLaunchOptions as resolveBrowserLaunchOptionsBase,
} from './session-browser-config.js'
import { CHROME_PATH } from './session-service-config.js'
type BrowserLike = {
on: (event: 'disconnected', listener: () => void) => void
close: () => Promise<void>
newContext: (options?: Record<string, unknown>) => Promise<any>
}
type SessionServiceErrorOptions = {
statusCode?: number
errorCode?: string
}
let browserPromise: Promise<BrowserLike> | null = null
export class SessionServiceError extends Error {
statusCode: number
errorCode: string
constructor(message: string, { statusCode = 500, errorCode = 'session_error' }: SessionServiceErrorOptions = {}) {
super(message)
this.name = 'SessionServiceError'
this.statusCode = statusCode
this.errorCode = errorCode
}
}
export async function warmupTencentBrowser() {
const browserLaunch = resolveBrowserLaunchOptions()
if (!browserLaunch.prewarm) {
return {
warmed: false,
reason: 'disabled',
browserLaunch,
}
}
await ensureBrowser()
return {
warmed: true,
reason: 'ready',
browserLaunch,
}
}
export async function ensureBrowser(): Promise<BrowserLike> {
if (!browserPromise) {
const launchOptions = resolveBrowserLaunchOptions()
browserPromise = (chromium.launch(buildChromiumLaunchOptions(launchOptions)) as Promise<BrowserLike>)
.then((browser) => {
browser.on('disconnected', () => {
browserPromise = null
})
return browser
})
.catch((error) => {
browserPromise = null
throw error
})
}
return browserPromise
}
export function resolveBrowserLaunchOptions() {
return resolveBrowserLaunchOptionsBase({
browserConfig: runtimeConfig.browser,
chromePath: CHROME_PATH,
})
}
export async function closeBrowserIfIdle({ activeSessionCount = 0 }: { activeSessionCount?: number } = {}): Promise<void> {
if (activeSessionCount > 0 || !browserPromise) {
return
}
if (resolveBrowserLaunchOptions().keepAlive) {
return
}
try {
const browser = await browserPromise
await browser.close()
} catch {
// ignore browser close failures
} finally {
browserPromise = null
}
}
function buildChromiumLaunchOptions(launchOptions: ReturnType<typeof resolveBrowserLaunchOptionsBase>) {
return buildChromiumLaunchOptionsBase(launchOptions, { chromePath: CHROME_PATH })
}