@casoon/auditmysite
Version:
Professional website analysis suite with robust accessibility testing, Core Web Vitals performance monitoring, SEO analysis, and content optimization insights. Features isolated browser contexts, retry mechanisms, and comprehensive API endpoints for profe
227 lines • 8.23 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WorkerPool = void 0;
const playwright_1 = require("playwright");
class WorkerPool {
constructor(options = {}) {
this.workers = [];
this.isInitialized = false;
this.workerIdCounter = 0;
this.options = {
maxWorkers: 3,
browserType: 'chromium',
headless: true,
timeout: 30000,
viewport: { width: 1920, height: 1080 },
userAgent: 'auditmysite/1.0',
enableResourceMonitoring: true,
maxMemoryUsage: 512, // 512 MB
maxCpuUsage: 80, // 80%
...options
};
}
async initialize() {
if (this.isInitialized) {
return;
}
console.log(`🔧 Initializing Worker Pool with ${this.options.maxWorkers} workers (${this.options.browserType})`);
// Browser-Instanz starten
const browser = await this.createBrowser();
// Worker erstellen
for (let i = 0; i < this.options.maxWorkers; i++) {
const worker = await this.createWorker(browser);
this.workers.push(worker);
}
this.isInitialized = true;
console.log(`✅ Worker Pool initialized with ${this.workers.length} workers`);
}
async createBrowser() {
const browserOptions = {
headless: this.options.headless,
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--disable-accelerated-2d-canvas',
'--no-first-run',
'--no-zygote',
'--disable-gpu'
]
};
switch (this.options.browserType) {
case 'firefox':
return await playwright_1.firefox.launch(browserOptions);
case 'webkit':
return await playwright_1.webkit.launch(browserOptions);
default:
return await playwright_1.chromium.launch(browserOptions);
}
}
async createWorker(browser) {
const context = await browser.newContext({
viewport: this.options.viewport,
userAgent: this.options.userAgent,
ignoreHTTPSErrors: true,
bypassCSP: true
});
const page = await context.newPage();
// Page-Optimierungen für Performance
await page.setDefaultTimeout(this.options.timeout);
await page.setDefaultNavigationTimeout(this.options.timeout);
const worker = {
id: ++this.workerIdCounter,
browser,
context,
page,
isBusy: false,
memoryUsage: 0,
cpuUsage: 0
};
return worker;
}
async getAvailableWorker() {
if (!this.isInitialized) {
throw new Error('Worker Pool not initialized. Call initialize() first.');
}
// Resource-Monitoring
if (this.options.enableResourceMonitoring) {
this.monitorResources();
}
// Verfügbaren Worker finden
const availableWorker = this.workers.find(worker => !worker.isBusy);
if (availableWorker) {
availableWorker.isBusy = true;
availableWorker.startTime = new Date();
return availableWorker;
}
return null;
}
async releaseWorker(worker) {
worker.isBusy = false;
worker.currentUrl = undefined;
worker.startTime = undefined;
// Page zurücksetzen
try {
await worker.page.goto('about:blank');
}
catch (error) {
// Ignore errors when resetting page
}
}
async executeTask(task, url) {
const worker = await this.getAvailableWorker();
if (!worker) {
throw new Error('No available workers in pool');
}
try {
worker.currentUrl = url;
const result = await task(worker);
return result;
}
finally {
await this.releaseWorker(worker);
}
}
monitorResources() {
this.workers.forEach(worker => {
if (worker.isBusy) {
// Memory Usage schätzen (Playwright bietet keine direkte API)
const memoryUsage = Math.random() * 100 + 50; // Simulierte Werte
worker.memoryUsage = memoryUsage;
// CPU Usage schätzen
const cpuUsage = Math.random() * 20 + 10; // Simulierte Werte
worker.cpuUsage = cpuUsage;
// Warnungen bei hoher Ressourcen-Nutzung
if (memoryUsage > this.options.maxMemoryUsage) {
console.warn(`⚠️ Worker ${worker.id} high memory usage: ${memoryUsage.toFixed(2)} MB`);
}
if (cpuUsage > this.options.maxCpuUsage) {
console.warn(`⚠️ Worker ${worker.id} high CPU usage: ${cpuUsage.toFixed(2)}%`);
}
}
});
}
getStats() {
const busyWorkers = this.workers.filter(w => w.isBusy).length;
const idleWorkers = this.workers.length - busyWorkers;
const totalMemoryUsage = this.workers.reduce((sum, w) => sum + w.memoryUsage, 0);
const totalCpuUsage = this.workers.reduce((sum, w) => sum + w.cpuUsage, 0);
return {
totalWorkers: this.workers.length,
busyWorkers,
idleWorkers,
averageMemoryUsage: this.workers.length > 0 ? totalMemoryUsage / this.workers.length : 0,
averageCpuUsage: this.workers.length > 0 ? totalCpuUsage / this.workers.length : 0,
totalMemoryUsage,
totalCpuUsage
};
}
getWorkerById(id) {
return this.workers.find(w => w.id === id);
}
getBusyWorkers() {
return this.workers.filter(w => w.isBusy);
}
getIdleWorkers() {
return this.workers.filter(w => !w.isBusy);
}
async resizePool(newSize) {
if (newSize < 1) {
throw new Error('Worker pool size must be at least 1');
}
const currentSize = this.workers.length;
if (newSize > currentSize) {
// Worker hinzufügen
const browser = this.workers[0]?.browser;
if (!browser) {
throw new Error('No browser instance available');
}
for (let i = currentSize; i < newSize; i++) {
const worker = await this.createWorker(browser);
this.workers.push(worker);
}
console.log(`➕ Added ${newSize - currentSize} workers to pool`);
}
else if (newSize < currentSize) {
// Worker entfernen (nur idle workers)
const idleWorkers = this.getIdleWorkers();
const workersToRemove = currentSize - newSize;
for (let i = 0; i < Math.min(workersToRemove, idleWorkers.length); i++) {
const worker = idleWorkers[i];
await this.destroyWorker(worker);
this.workers = this.workers.filter(w => w.id !== worker.id);
}
console.log(`➖ Removed ${Math.min(workersToRemove, idleWorkers.length)} workers from pool`);
}
}
async destroyWorker(worker) {
try {
await worker.page.close();
await worker.context.close();
}
catch (error) {
console.warn(`Warning: Error destroying worker ${worker.id}:`, error);
}
}
async cleanup() {
console.log('🧹 Cleaning up Worker Pool...');
// Alle Worker zerstören
for (const worker of this.workers) {
await this.destroyWorker(worker);
}
this.workers = [];
this.isInitialized = false;
console.log('✅ Worker Pool cleaned up');
}
getInitializationStatus() {
return this.isInitialized;
}
getMaxWorkers() {
return this.options.maxWorkers;
}
setMaxWorkers(max) {
this.options.maxWorkers = max;
}
}
exports.WorkerPool = WorkerPool;
//# sourceMappingURL=worker-pool.js.map