Descripción general
La funcionalidad de colas de Laravel ofrece dos tipos de control de ejecución: la deduplicación (Unique) y el debounce (Debounce) de jobs. Ambos mecanismos sirven para «evitar ejecuciones innecesarias cuando el mismo job se despacha varias veces», pero su comportamiento es distinto.Unique Jobs — ShouldBeUnique
Mientras el mismo job esté en la cola, se ignoran los despachos adicionales.
UpdateSearchIndex esté encolado (o en procesamiento), cualquier intento de despachar el mismo job se ignora.
Restringir la unicidad con una clave — UniqueFor + uniqueId()
Si aun tratándose de la misma clase de job quieres tratar «actualizar el producto A» y «actualizar el producto B» como jobs distintos, define la clave con el método uniqueId().
- El valor devuelto por
uniqueId()es la clave del bloqueo en caché. - Al indicar
#[UniqueFor(segundos)], el bloqueo se libera automáticamente tras esos segundos (medida de seguridad para el caso en que el job no llegue a procesarse).
Especificar el driver de caché — uniqueVia()
Si quieres utilizar un driver de caché distinto al predeterminado, implementa uniqueVia().
Unique Jobs requiere un driver de caché que soporte bloqueos atómicos (
redis, database, memcached, dynamodb, file o array).ShouldBeUnique vs ShouldBeUniqueUntilProcessing
El bloqueo de ShouldBeUnique se mantiene hasta que el job se completa o alcanza el límite de reintentos. Esto puede ser un problema en algunos casos.
Ejemplo: hay 1 UpdateSearchIndex(product_id: 42) en la cola y quieres volver a despachar el mismo job justo después de que el worker empiece a procesarlo. Con ShouldBeUnique, el segundo job no se encolará hasta que finalice el procesamiento.
En este caso utiliza ShouldBeUniqueUntilProcessing. Como el bloqueo se libera justo antes de comenzar el procesamiento, se puede despachar el siguiente en cuanto el worker toma el job.
Comparativa
Debounced Jobs — #[DebounceFor]
El atributo
DebounceFor es una funcionalidad añadida en Laravel 13.- El valor devuelto por
debounceId()identifica el job (el debounce se aplica de forma independiente por cada ID de producto). - Aunque se despache 10 veces con el mismo
productIden 30 s, solo se ejecuta el último.
maxWait — límite del tiempo máximo de espera
Con datos que se actualizan con mucha frecuencia, el debounce podría prolongarse indefinidamente y el job podría no ejecutarse nunca. Con maxWait puedes fijar el retraso máximo.
Especificar el driver de caché — debounceVia()
Evento JobDebounced
Los jobs que quedan sobrescritos por un despacho posterior emiten el evento Illuminate\Queue\Events\JobDebounced y se eliminan de la cola. Escuchando este evento puedes rastrear y monitorizar los jobs debounced.
Cuál elegir
Implementación interna
Mecanismo de bloqueo de Unique Jobs
Cuando se despacha un jobShouldBeUnique, Laravel obtiene internamente un bloqueo atómico de la caché. La clave del bloqueo tiene el siguiente formato:
Implementación de los Debounced Jobs
DebounceFor utiliza internamente una entrada de caché que gestiona una «ventana de debounce». Cada vez que llega un nuevo despacho:
- Se elimina el job existente de la cola (emitiendo el evento
JobDebounced). - Se añade el nuevo job a la cola (con el retraso indicado por los segundos de debounce).
- Se reinicia el temporizador en la caché.
maxWait está definido, también se registra la marca de tiempo del primer despacho para evitar que el debounce se prolongue más allá de los segundos de maxWait.