web-search-mcp
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
import { chromium, firefox, webkit } from 'playwright';
|
||||
export class BrowserPool {
|
||||
browsers = new Map();
|
||||
maxBrowsers;
|
||||
browserTypes;
|
||||
currentBrowserIndex = 0;
|
||||
headless;
|
||||
lastUsedBrowserType = '';
|
||||
constructor() {
|
||||
// Read configuration from environment variables
|
||||
this.maxBrowsers = parseInt(process.env.MAX_BROWSERS || '3', 10);
|
||||
this.headless = process.env.BROWSER_HEADLESS !== 'false'; // Default to true
|
||||
// Configure browser types based on environment
|
||||
const browserTypesEnv = process.env.BROWSER_TYPES || 'chromium,firefox';
|
||||
this.browserTypes = browserTypesEnv.split(',').map(type => type.trim());
|
||||
console.log(`[BrowserPool] Configuration: maxBrowsers=${this.maxBrowsers}, headless=${this.headless}, types=${this.browserTypes.join(',')}`);
|
||||
}
|
||||
async getBrowser() {
|
||||
// Rotate between browser types for variety
|
||||
const browserType = this.browserTypes[this.currentBrowserIndex % this.browserTypes.length];
|
||||
this.currentBrowserIndex++;
|
||||
this.lastUsedBrowserType = browserType;
|
||||
if (this.browsers.has(browserType)) {
|
||||
const browser = this.browsers.get(browserType);
|
||||
// Check if browser is still connected and healthy
|
||||
try {
|
||||
if (browser.isConnected()) {
|
||||
// Quick health check by trying to create and close a context
|
||||
// Use minimal options to avoid Firefox isMobile issues
|
||||
const testContext = await browser.newContext({
|
||||
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36'
|
||||
});
|
||||
await testContext.close();
|
||||
return browser;
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
console.log(`[BrowserPool] Browser ${browserType} health check failed:`, error);
|
||||
// Browser is unhealthy, remove it and close if possible
|
||||
this.browsers.delete(browserType);
|
||||
try {
|
||||
await browser.close();
|
||||
}
|
||||
catch (closeError) {
|
||||
console.log(`[BrowserPool] Error closing unhealthy browser:`, closeError);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Launch new browser
|
||||
console.log(`[BrowserPool] Launching new ${browserType} browser`);
|
||||
const launchOptions = {
|
||||
headless: this.headless,
|
||||
args: [
|
||||
'--no-sandbox',
|
||||
'--disable-blink-features=AutomationControlled',
|
||||
'--disable-dev-shm-usage',
|
||||
'--disable-gpu',
|
||||
'--no-first-run',
|
||||
'--no-default-browser-check',
|
||||
'--disable-default-apps',
|
||||
'--disable-extensions',
|
||||
'--disable-background-timer-throttling',
|
||||
'--disable-backgrounding-occluded-windows',
|
||||
'--disable-renderer-backgrounding',
|
||||
'--disable-features=TranslateUI',
|
||||
'--disable-ipc-flooding-protection',
|
||||
],
|
||||
};
|
||||
let browser;
|
||||
try {
|
||||
switch (browserType) {
|
||||
case 'chromium':
|
||||
browser = await chromium.launch(launchOptions);
|
||||
break;
|
||||
case 'firefox':
|
||||
browser = await firefox.launch(launchOptions);
|
||||
break;
|
||||
case 'webkit':
|
||||
browser = await webkit.launch(launchOptions);
|
||||
break;
|
||||
default:
|
||||
browser = await chromium.launch(launchOptions);
|
||||
}
|
||||
this.browsers.set(browserType, browser);
|
||||
// Clean up old browsers if we have too many
|
||||
if (this.browsers.size > this.maxBrowsers) {
|
||||
const oldestBrowser = this.browsers.entries().next().value;
|
||||
if (oldestBrowser) {
|
||||
try {
|
||||
await oldestBrowser[1].close();
|
||||
}
|
||||
catch (error) {
|
||||
console.error(`[BrowserPool] Error closing old browser:`, error);
|
||||
}
|
||||
this.browsers.delete(oldestBrowser[0]);
|
||||
}
|
||||
}
|
||||
return browser;
|
||||
}
|
||||
catch (error) {
|
||||
console.error(`[BrowserPool] Failed to launch ${browserType} browser:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async closeAll() {
|
||||
console.log(`[BrowserPool] Closing ${this.browsers.size} browsers`);
|
||||
const closePromises = Array.from(this.browsers.values()).map(browser => browser.close().catch(error => console.error('Error closing browser:', error)));
|
||||
await Promise.all(closePromises);
|
||||
this.browsers.clear();
|
||||
}
|
||||
getLastUsedBrowserType() {
|
||||
return this.lastUsedBrowserType;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=browser-pool.js.map
|
||||
Reference in New Issue
Block a user