@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
286 lines • 9.29 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PriorityQueue = void 0;
class PriorityQueue {
constructor(options = {}) {
this.queue = [];
this.processing = new Set();
this.completed = [];
this.failed = [];
this.itemIdCounter = 0;
this.options = {
maxSize: 1000,
defaultPriority: 5,
maxAttempts: 3,
retryDelay: 1000,
enablePriorityBoost: true,
priorityBoostThreshold: 30, // 30 Sekunden
priorityBoostAmount: 2,
...options
};
}
enqueue(data, priority, id) {
if (this.queue.length >= this.options.maxSize) {
throw new Error(`Queue is full (max size: ${this.options.maxSize})`);
}
const itemId = id || `item_${++this.itemIdCounter}`;
const item = {
id: itemId,
data,
priority: priority ?? this.options.defaultPriority,
timestamp: new Date(),
attempts: 0,
maxAttempts: this.options.maxAttempts,
status: 'pending'
};
this.queue.push(item);
this.sortQueue();
return itemId;
}
dequeue() {
if (this.queue.length === 0) {
return null;
}
// Priority Boost für alte Items
if (this.options.enablePriorityBoost) {
this.applyPriorityBoost();
}
const item = this.queue.shift();
item.status = 'processing';
item.startedAt = new Date();
this.processing.add(item.id);
return item;
}
peek() {
if (this.queue.length === 0) {
return null;
}
return this.queue[0];
}
complete(id, result) {
const item = this.findItem(id);
if (!item || item.status !== 'processing') {
return false;
}
item.status = 'completed';
item.result = result;
item.completedAt = new Date();
item.duration = item.completedAt.getTime() - item.startedAt.getTime();
this.processing.delete(id);
this.completed.push(item);
return true;
}
fail(id, error) {
const item = this.findItem(id);
if (!item || item.status !== 'processing') {
return false;
}
item.attempts++;
item.error = error;
if (item.attempts >= item.maxAttempts) {
item.status = 'failed';
item.completedAt = new Date();
item.duration = item.completedAt.getTime() - item.startedAt.getTime();
this.processing.delete(id);
this.failed.push(item);
}
else {
item.status = 'retrying';
item.priority += this.options.priorityBoostAmount; // Boost für Retry
// Zurück in die Queue für Retry
this.queue.push(item);
this.sortQueue();
}
this.processing.delete(id);
return true;
}
retry(id) {
const item = this.findItem(id);
if (!item || item.status !== 'retrying') {
return false;
}
item.status = 'pending';
item.startedAt = undefined;
item.completedAt = undefined;
item.duration = undefined;
this.sortQueue();
return true;
}
remove(id) {
const index = this.queue.findIndex(item => item.id === id);
if (index === -1) {
return false;
}
this.queue.splice(index, 1);
this.processing.delete(id);
return true;
}
clear() {
this.queue = [];
this.processing.clear();
this.completed = [];
this.failed = [];
}
getById(id) {
return this.findItem(id);
}
updatePriority(id, newPriority) {
const item = this.findItem(id);
if (!item) {
return false;
}
item.priority = newPriority;
this.sortQueue();
return true;
}
getStats() {
const now = new Date();
const total = this.queue.length + this.processing.size + this.completed.length + this.failed.length;
const pending = this.queue.filter(item => item.status === 'pending').length;
const processing = this.processing.size;
const completed = this.completed.length;
const failed = this.failed.length;
const retrying = this.queue.filter(item => item.status === 'retrying').length;
const allItems = [...this.queue, ...this.completed, ...this.failed];
const averagePriority = allItems.length > 0
? allItems.reduce((sum, item) => sum + item.priority, 0) / allItems.length
: 0;
const averageWaitTime = this.completed.length > 0
? this.completed.reduce((sum, item) => sum + (item.startedAt.getTime() - item.timestamp.getTime()), 0) / this.completed.length
: 0;
const averageProcessingTime = this.completed.length > 0
? this.completed.reduce((sum, item) => sum + (item.duration || 0), 0) / this.completed.length
: 0;
const oldestItem = this.queue.length > 0 ? this.queue[this.queue.length - 1] : undefined;
const newestItem = this.queue.length > 0 ? this.queue[0] : undefined;
return {
total,
pending,
processing,
completed,
failed,
retrying,
averagePriority: Math.round(averagePriority * 100) / 100,
averageWaitTime: Math.round(averageWaitTime),
averageProcessingTime: Math.round(averageProcessingTime),
oldestItem,
newestItem
};
}
getPendingItems() {
return this.queue.filter(item => item.status === 'pending');
}
getProcessingItems() {
return Array.from(this.processing).map(id => this.findItem(id)).filter(Boolean);
}
getCompletedItems() {
return [...this.completed];
}
getFailedItems() {
return [...this.failed];
}
getRetryingItems() {
return this.queue.filter(item => item.status === 'retrying');
}
isEmpty() {
return this.queue.length === 0 && this.processing.size === 0;
}
isFull() {
return this.queue.length >= this.options.maxSize;
}
size() {
return this.queue.length;
}
processingSize() {
return this.processing.size;
}
// Private Methods
findItem(id) {
// In Queue suchen
const queueItem = this.queue.find(item => item.id === id);
if (queueItem)
return queueItem;
// In Processing suchen
if (this.processing.has(id)) {
// Item ist in Processing, aber nicht mehr in Queue
// Das sollte nicht passieren, aber zur Sicherheit
return null;
}
// In Completed suchen
const completedItem = this.completed.find(item => item.id === id);
if (completedItem)
return completedItem;
// In Failed suchen
const failedItem = this.failed.find(item => item.id === id);
if (failedItem)
return failedItem;
return null;
}
sortQueue() {
this.queue.sort((a, b) => {
// Höchste Priorität zuerst
if (a.priority !== b.priority) {
return b.priority - a.priority;
}
// Bei gleicher Priorität: Ältestes zuerst (FIFO)
return a.timestamp.getTime() - b.timestamp.getTime();
});
}
applyPriorityBoost() {
const now = new Date();
const threshold = this.options.priorityBoostThreshold * 1000; // zu Millisekunden
this.queue.forEach(item => {
const waitTime = now.getTime() - item.timestamp.getTime();
if (waitTime > threshold && item.status === 'pending') {
item.priority += this.options.priorityBoostAmount;
}
});
// Neu sortieren nach Boost
this.sortQueue();
}
// Utility Methods
getMaxSize() {
return this.options.maxSize;
}
setMaxSize(maxSize) {
this.options.maxSize = maxSize;
}
getDefaultPriority() {
return this.options.defaultPriority;
}
setDefaultPriority(priority) {
this.options.defaultPriority = priority;
}
getMaxAttempts() {
return this.options.maxAttempts;
}
setMaxAttempts(maxAttempts) {
this.options.maxAttempts = maxAttempts;
}
// Batch Operations
enqueueBatch(items) {
const ids = [];
for (const item of items) {
try {
const id = this.enqueue(item.data, item.priority, item.id);
ids.push(id);
}
catch (error) {
console.warn(`Failed to enqueue item: ${error}`);
}
}
return ids;
}
dequeueBatch(count) {
const items = [];
for (let i = 0; i < count && this.queue.length > 0; i++) {
const item = this.dequeue();
if (item) {
items.push(item);
}
}
return items;
}
}
exports.PriorityQueue = PriorityQueue;
//# sourceMappingURL=priority-queue.js.map