Aperçu
La queue de Laravel propose deux mécanismes de contrôle d’exécution des jobs : la déduplication (Unique) et le debounce. Les deux visent à « éviter d’exécuter le même job plusieurs fois lorsqu’il est dispatché à répétition », mais leur comportement diffère.Unique Jobs — ShouldBeUnique
Tant qu’un même job est présent dans la queue, tout dispatch supplémentaire est ignoré.
UpdateSearchIndex est en attente (ou en cours de traitement), toute tentative de dispatcher le même job est ignorée.
Restreindre la contrainte d’unicité par clé — UniqueFor + uniqueId()
Si vous souhaitez que « la mise à jour du produit A » et « la mise à jour du produit B » soient traitées comme deux jobs distincts même si la classe est identique, définissez la clé via la méthode uniqueId().
- La valeur retournée par
uniqueId()sert de clé au verrou de cache. - Avec
#[UniqueFor(secondes)], le verrou est libéré automatiquement à l’expiration du délai indiqué (filet de sécurité au cas où le job ne serait pas traité).
Choisir le driver de cache — uniqueVia()
Pour utiliser un autre driver de cache que celui par défaut, implémentez uniqueVia().
Unique Jobs requiert un driver de cache prenant en charge les verrous atomiques (
redis, database, memcached, dynamodb, file, array).ShouldBeUnique vs ShouldBeUniqueUntilProcessing
Le verrou de ShouldBeUnique est conservé jusqu’à ce que le job soit terminé ou ait atteint son nombre maximal de tentatives, ce qui peut poser problème.
Exemple : un seul UpdateSearchIndex(product_id: 42) est présent dans la queue et vous voulez pouvoir redispatcher le même job juste après que le worker a commencé son traitement. Avec ShouldBeUnique, le deuxième job ne peut pas rejoindre la queue avant la fin du traitement.
Dans ce cas, utilisez ShouldBeUniqueUntilProcessing. Le verrou est libéré juste avant le début du traitement, ce qui autorise un nouveau dispatch dès que le worker prend en charge le job.
Récapitulatif comparatif
Debounced Jobs — #[DebounceFor]
L’attribut
DebounceFor a été ajouté dans Laravel 13.- La valeur retournée par
debounceId()identifie le job (chaqueproductIdapplique un debounce indépendant). - Même si 10 dispatches ont lieu en 30 secondes avec le même
productId, seul le dernier sera exécuté.
maxWait — délai d’attente maximum
Pour des données mises à jour très fréquemment, le debounce risque de se prolonger indéfiniment et le job de ne jamais être exécuté. L’option maxWait définit un délai maximal.
Choisir le driver de cache — debounceVia()
L’événement JobDebounced
Un job écrasé par un dispatch ultérieur émet l’événement Illuminate\Queue\Events\JobDebounced et est retiré de la queue. En écoutant cet événement, vous pouvez tracer et monitorer les jobs mis en debounce.
Lequel choisir ?
Implémentation interne
Verrouillage des Unique Jobs
Lorsqu’un jobShouldBeUnique est dispatché, Laravel acquiert en interne un verrou atomique du cache. La clé de verrou est de la forme :
Implémentation des Debounced Jobs
DebounceFor s’appuie en interne sur une entrée de cache qui gère la « fenêtre de debounce ». À chaque nouveau dispatch :
- Le job existant est retiré de la queue (émission de l’événement
JobDebounced). - Le nouveau job est ajouté à la queue (avec un délai égal au nombre de secondes du debounce).
- Le minuteur en cache est réinitialisé.
maxWait est défini, l’horodatage du premier dispatch est également enregistré, ce qui empêche le debounce de dépasser maxWait secondes à partir de ce premier moment.