miércoles, 25 de junio de 2025

Implementación de Colas Prioritarias con SplPriorityQueue en PHP para Tareas Asíncronas

Implementación de Colas Prioritarias con SplPriorityQueue en PHP para Tareas Asíncronas

En el desarrollo de aplicaciones PHP complejas, la gestión eficiente de tareas asíncronas es crucial. Una forma poderosa de lograrlo es mediante el uso de colas prioritarias. PHP proporciona la clase SplPriorityQueue para implementar estas colas, permitiendo asignar prioridades a las tareas y ejecutarlas en el orden adecuado.

Este artículo explora cómo utilizar SplPriorityQueue para gestionar tareas asíncronas en un contexto PHP, proporcionando un ejemplo práctico y listo para usar.


<?php

/**
 * Clase para representar una tarea.
 */
class Tarea {
    public $id;
    public $descripcion;

    public function __construct($id, $descripcion) {
        $this->id = $id;
        $this->descripcion = $descripcion;
    }

    public function ejecutar() {
        // Simulación de la ejecución de la tarea.
        echo "Ejecutando tarea " . $this->id . ": " . $this->descripcion . PHP_EOL;
        sleep(1); // Simula un proceso que tarda un segundo.
    }
}

/**
 * Clase para gestionar la cola de prioridades de tareas.
 */
class GestorTareas {
    private $colaPrioridad;

    public function __construct() {
        $this->colaPrioridad = new SplPriorityQueue();
    }

    /**
     * Agrega una tarea a la cola con una prioridad específica.
     *
     * @param Tarea $tarea La tarea a agregar.
     * @param int $prioridad La prioridad de la tarea (mayor valor = mayor prioridad).
     */
    public function agregarTarea(Tarea $tarea, int $prioridad) {
        $this->colaPrioridad->insert($tarea, $prioridad);
    }

    /**
     * Ejecuta las tareas en la cola por orden de prioridad.
     */
    public function ejecutarTareas() {
        // SplPriorityQueue itera de menor a mayor prioridad, por lo que necesitamos extraer
        // en orden inverso. Esto lo hacemos creando una copia.
        $colaCopia = clone $this->colaPrioridad;
        $colaCopia->setExtractFlags(SplPriorityQueue::EXTR_DATA); // Extraer sólo los datos.
        $colaCopia->rewind(); // Regresar al inicio.

        while ($colaCopia->valid()) {
            $tarea = $colaCopia->extract();
            $tarea->ejecutar();
        }
    }
}

// Ejemplo de uso
$gestor = new GestorTareas();

$gestor->agregarTarea(new Tarea(1, "Enviar correo electrónico"), 2);
$gestor->agregarTarea(new Tarea(2, "Generar informe"), 1);
$gestor->agregarTarea(new Tarea(3, "Actualizar base de datos"), 3);

$gestor->ejecutarTareas();

// Salida esperada:
// Ejecutando tarea 3: Actualizar base de datos
// Ejecutando tarea 1: Enviar correo electrónico
// Ejecutando tarea 2: Generar informe

El código anterior define una clase `Tarea` simple y un `GestorTareas` que utiliza `SplPriorityQueue` para gestionar las tareas. La función `agregarTarea` inserta tareas en la cola, asignando una prioridad. La función `ejecutarTareas` extrae y ejecuta las tareas en el orden de prioridad definido. Es importante notar que `SplPriorityQueue` itera sobre las prioridades de menor a mayor, por lo que se clona la cola para invertir el orden de extracción.

Este patrón puede ser extendido para integrar con sistemas de colas de mensajes como RabbitMQ o Redis para una gestión más robusta y distribuida de tareas asíncronas. Además, se puede integrar con sistemas de logging para monitorear la ejecución de las tareas y detectar posibles errores.

No hay comentarios:

Publicar un comentario