@casoon/auditmysite
Version:
A comprehensive command-line tool for automated accessibility, security, performance, and SEO testing using Playwright and pa11y, based on sitemap URLs
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