JavaScripthardJavaScript

Queue System with Priority

Queue management system with priority levels and concurrency control

01

The problem

Need to manage async tasks with priorities and concurrency limits

02

The solution

JavaScript
class PriorityQueue {
  constructor(maxConcurrent = 3) {
    this.queue = [];
    this.running = 0;
    this.maxConcurrent = maxConcurrent;
    this.nextId = 1;
  }
  
  add(task, priority = 0) {
    const taskId = this.nextId++;
    const queueItem = {
      id: taskId,
      task,
      priority,
      addedAt: Date.now(),
      status: 'pending'
    };
    
    this.queue.push(queueItem);
    this.queue.sort((a, b) => {
      if (a.priority !== b.priority) {
        return b.priority - a.priority; // Higher priority first
      }
      return a.addedAt - b.addedAt; // Older first if same priority
    });
    
    this.process();
    return taskId;
  }
  
  async process() {
    if (this.running >= this.maxConcurrent || this.queue.length === 0) {
      return;
    }
    
    const nextItem = this.queue.shift();
    this.running++;
    nextItem.status = 'running';
    
    try {
      const result = await nextItem.task();
      nextItem.status = 'completed';
      nextItem.result = result;
      nextItem.completedAt = Date.now();
    } catch (error) {
      nextItem.status = 'failed';
      nextItem.error = error;
      nextItem.failedAt = Date.now();
    } finally {
      this.running--;
      this.process(); // Try to process next item
    }
  }
  
  getStatus(id) {
    const item = this.queue.find(item => item.id === id) ||
      this.completed.find(item => item.id === id);
    return item ? item.status : 'not_found';
  }
  
  setMaxConcurrent(max) {
    this.maxConcurrent = max;
    this.process();
  }
  
  clearPending() {
    this.queue = this.queue.filter(item => item.status === 'running');
  }
  
  getStats() {
    return {
      pending: this.queue.length,
      running: this.running,
      maxConcurrent: this.maxConcurrent,
      totalInQueue: this.queue.length + this.running
    };
  }
}

// Task Factory
function createTask(name, duration, shouldFail = false) {
  return async () => {
    console.log(`Starting task: ${name}`);
    await new Promise(resolve => setTimeout(resolve, duration));
    
    if (shouldFail) {
      throw new Error(`Task ${name} failed!`);
    }
    
    console.log(`Completed task: ${name}`);
    return `Result of ${name}`;
  };
}

03

Put it to work

Example
const taskQueue = new PriorityQueue(2); // Max 2 concurrent tasks

// Add tasks with different priorities
taskQueue.add(createTask('Task 1', 1000), 1);
taskQueue.add(createTask('Task 2', 2000), 3); // High priority
taskQueue.add(createTask('Task 3', 1500), 2);
taskQueue.add(createTask('Task 4', 500), 1);

// Get queue stats
console.log(taskQueue.getStats());
// { pending: 2, running: 2, maxConcurrent: 2, totalInQueue: 4 }

// Update concurrency
taskQueue.setMaxConcurrent(3);

// Add task that might fail
taskQueue.add(createTask('Failing Task', 1000, true), 1);

// Clear pending tasks
// taskQueue.clearPending();