后端迁移会话运行时模块
This commit is contained in:
@@ -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 })
|
||||
}
|
||||
Reference in New Issue
Block a user