Aller au contenu

Workers

Les workers sont des processus de longue durée qui interrogent la base de données pour trouver les tâches en attente, les exécutent et font avancer les workflows. La commande wp queuety work s’exécute dans WP-CLI, tandis que la file d’attente elle-même est revendiquée directement depuis MySQL via le meilleur pilote de base de données Queuety disponible.

L’extension installe également une solution de repli WordPress cron par défaut, exécutée une fois par minute, pour les environnements sans accès au shell. Cette page porte sur les workers WP-CLI dédiés, le mode de déploiement recommandé pour un débit supérieur.

Démarrer un worker

Shell
wp queuety work

Cette commande démarre un worker unique sur la file d’attente default. Il s’exécute en boucle : il revendique une tâche, l’exécute, puis recommence. Lorsque la file est vide, il attend QUEUETY_WORKER_SLEEP seconde (1 par défaut) avant de l’interroger à nouveau.

Options

Option Description
--queue=<queue> Queue(s) à traiter, séparées par des virgules pour définir l’ordre de priorité (default par défaut)
--once Traiter une seule tâche au maximum, puis quitter
--workers=<n> Démarrer N processus workers (nécessite les extensions pcntl et posix)
--min-workers=<n> Nombre minimal de workers d’un pool adaptatif. Nécessite --max-workers
--max-workers=<n> Nombre maximal de workers d’un pool adaptatif
Shell
# Process a specific queue
wp queuety work --queue=emails

# Process at most one job and exit
wp queuety work --once

# Run 4 concurrent workers
wp queuety work --workers=4

# Scale between 2 and 6 workers as backlog changes
wp queuety work --queue=providers --min-workers=2 --max-workers=6

Priorités entre plusieurs files d’attente

Un seul worker peut traiter plusieurs files d’attente selon leur ordre de priorité. Transmettez une liste de noms de files séparés par des virgules à --queue :

Shell
wp queuety work --queue=critical,default,low

Le worker tente de revendiquer une tâche dans chaque file, selon l’ordre indiqué. Il vérifie d’abord critical. Si critical contient une tâche, il la traite. Si critical est vide, il passe à default, puis à low. Ainsi, les files prioritaires se vident toujours avant celles de priorité inférieure.

Fonctionnement de l’ordre de priorité

À chaque itération, le worker tente de revendiquer une tâche dans la première file de la liste. Si cette file est vide ou en pause, il passe à la suivante et continue ainsi jusqu’à trouver une tâche ou épuiser la liste. Si aucune tâche n’est trouvée, le worker attend et réessaie. Ce modèle applique une priorité stricte : un flux continu de tâches critical affamera default et low. Si les files moins prioritaires doivent garantir un débit, utilisez plutôt des workers dédiés.

Utiliser plusieurs files avec PHP

Les méthodes Worker::run() et Worker::flush() acceptent une chaîne ou un tableau :

PHP
// Comma-separated string
Queuety::worker()->run( 'critical,default,low' );

// Array
Queuety::worker()->run( [ 'critical', 'default', 'low' ] );

// flush() also supports multi-queue
$count = Queuety::worker()->flush( 'critical,default,low' );

Stratégies de déploiement

Des workers dédiés par file d’attente vous donnent un contrôle total sur la concurrence et l’isolation. Chaque file a son propre worker process(es) et ne peut pas être affamée par les autres files :

Ini
[program:queuety-critical]
command=wp queuety work --queue=critical
numprocs=4

[program:queuety-default]
command=wp queuety work --queue=default
numprocs=2

[program:queuety-low]
command=wp queuety work --queue=low
numprocs=1

Un ordre de priorité avec un seul worker est plus simple à gérer et convient lorsque les files de priorité inférieure peuvent tolérer des délais :

Ini
[program:queuety-worker]
command=wp queuety work --queue=critical,default,low
numprocs=2

Vous pouvez aussi combiner les deux approches : des workers dédiés pour critical afin de garantir le débit, et un worker utilisant l’ordre de priorité pour tout le reste :

Ini
[program:queuety-critical]
command=wp queuety work --queue=critical
numprocs=2

[program:queuety-fallback]
command=wp queuety work --queue=default,low
numprocs=2

Admission tenant compte des ressources

Les workers ne se contentent pas de revendiquer la prochaine ligne en attente. Avant le démarrage d’une tâche revendiquée, Queuety peut appliquer des contrôles d’admission généraux, fondés sur le groupe de concurrence de la tâche et le profil d’exécution récent de son gestionnaire.

Pour en savoir plus sur le modèle général, notamment sur son interaction avec les métadonnées des tâches et les budgets de workflow, consultez Gestion des ressources.

Un groupe de concurrence fixe un plafond commun à plusieurs gestionnaires ou catégories de tâches. Si vous attribuez le même groupe et la même limite à plusieurs fournisseurs coûteux en ressources, un worker libère les tâches nouvellement revendiquées au lieu de les démarrer lorsque le groupe a atteint son plafond. Cela évite que des files indépendantes ne submergent un même système en aval simplement parce que plusieurs workers sont inactifs.

Les journaux d’exécution récents alimentent également un profil d’admission simple. Lorsque l’admission tenant compte des ressources est activée, Queuety examine la durée moyenne récente et le pic mémoire du gestionnaire qu’il s’apprête à exécuter. Si le worker actuel approche déjà de sa limite mémoire configurée, si le budget pondéré d’une file ou d’un groupe de fournisseurs est atteint, si le conteneur actuel ne semble pas disposer d’assez de mémoire pour le profil observé du gestionnaire, ou si une exécution de type --once approche de sa limite de temps, Queuety reporte la tâche au lieu de démarrer un travail peu susceptible de se terminer correctement.

Vous activez cette règle dans la définition du travail, et non dans la commande du worker :

PHP
class CallProviderStep implements \Queuety\Step {
    public function handle( array $state ): array {
        // ...
    }

    public function config(): array {
        return [
            'concurrency_group' => 'providers',
            'concurrency_limit' => 3,
            'cost_units' => 5,
        ];
    }
}

Les mêmes métadonnées peuvent être associées à des classes de tâches distribuables au moyen de propriétés publiques, ou à une distribution individuelle via PendingJob::concurrency_group() et PendingJob::cost_units().

Le profil d’admission côté worker est contrôlé par les constantes suivantes :

Constante Description
QUEUETY_RESOURCE_ADMISSION Activer ou désactiver les contrôles d’admission fondés sur le profil
QUEUETY_RESOURCE_PROFILE_WINDOW_MINUTES Période à examiner pour établir les profils récents des gestionnaires
QUEUETY_RESOURCE_PROFILE_TTL Durée de vie du cache des profils récents des gestionnaires
QUEUETY_RESOURCE_MEMORY_HEADROOM_MB Marge mémoire réservée avant d’admettre une autre tâche
QUEUETY_RESOURCE_SYSTEM_MEMORY_AWARENESS Activer ou désactiver les contrôles au mieux de la mémoire du conteneur ou de l’hôte
QUEUETY_RESOURCE_SYSTEM_MEMORY_HEADROOM_MB Marge mémoire système réservée avant d’admettre une autre tâche
QUEUETY_RESOURCE_QUEUE_COST_BUDGETS Budgets de coûts pondérés associés au nom de la file d’attente
QUEUETY_RESOURCE_GROUP_COST_BUDGETS Budgets de coûts pondérés associés à concurrency_group
QUEUETY_RESOURCE_TIME_HEADROOM_MS Marge de temps réservée pour les exécutions de workers ponctuelles

Cycle de vie des workers

Un worker s’arrête correctement après avoir terminé sa tâche en cours dès que l’une des conditions suivantes est remplie :

Condition Configuration
Nombre maximal de tâches traitées QUEUETY_WORKER_MAX_JOBS (1000 par défaut)
Limite mémoire dépassée QUEUETY_WORKER_MAX_MEMORY (128 Mo par défaut)

Une fois arrêté, le worker quitte le processus proprement. En production, un gestionnaire de processus le redémarre automatiquement.

Les signaux ne sont pas encore gérés proprement (#4). Un processus wp queuety work unique n’installe aucun gestionnaire de signaux ; SIGTERM ou SIGINT (Ctrl+C) l’arrête donc immédiatement, même au milieu d’une tâche. Cette tâche reste processing jusqu’à ce que la récupération des tâches obsolètes la réinitialise après QUEUETY_STALE_TIMEOUT secondes ; veillez donc à ce que les gestionnaires puissent être réessayés sans risque. Un pool de workers transmet SIGTERM à ses processus enfants, mais ceux-ci ne le traitent pas. Le pool continue donc de fonctionner jusqu’à ce qu’ils s’arrêtent pour l’une des raisons ci-dessus. Pour arrêter un pool, configurez un délai d’arrêt dans votre gestionnaire de processus, à l’issue duquel il envoie SIGKILL.

Concurrence entre plusieurs workers

L’option --workers=N crée N processus enfants avec pcntl_fork(). Chaque enfant crée sa propre connexion à la base de données et traite les tâches de façon indépendante. Le processus parent surveille les enfants et redémarre ceux qui plantent.

Shell
wp queuety work --queue=default --workers=4

Prérequis : Les extensions pcntl et posix PHP doivent être installées (sans pcntl, la commande échoue avec « pcntl extension is required for --workers=N. »). Chaque enfant utilise sa propre connexion à la base de données ; le réglage MySQL max_connections doit donc être adapté à la taille du pool. Les pools adaptatifs (--min-workers/--max-workers) ont les mêmes prérequis.

Pools de workers adaptatifs

Les pools adaptatifs maintiennent un nombre minimal de workers prêts à traiter des tâches, puis augmentent ou diminuent leur nombre dans la plage configurée :

Shell
wp queuety work --queue=providers --min-workers=2 --max-workers=6

Le processus parent surveille l’arriéré de tâches pouvant être revendiquées dans les files sélectionnées et ajuste le nombre de processus enfants en fonction de cet arriéré, sans dépasser le maximum configuré. Lorsque l’activité de la file diminue, le pool attend la fin du délai d’inactivité avant de réduire ses effectifs, afin que les courtes pointes d’activité ne provoquent pas un renouvellement immédiat des processus.

La montée en charge reste prudente. Lorsque Queuety peut lire les données de télémétrie mémoire du conteneur ou de l’hôte, il refuse d’ajouter des processus enfants s’il ne reste pas assez de mémoire pour un worker supplémentaire.

La boucle de mise à l’échelle côté parent est contrôlée par :

Constante Description
QUEUETY_WORKER_POOL_SCALE_INTERVAL Fréquence à laquelle le processus parent ajuste la taille du pool
QUEUETY_WORKER_POOL_IDLE_GRACE Durée pendant laquelle l’arriéré doit rester inactif avant la réduction du pool

Récupération des tâches obsolètes

Si un worker plante pendant le traitement d’une tâche, celle-ci reste à l’état processing. Un worker de longue durée vérifie environ une fois par minute si des tâches sont restées à l’état processing plus de QUEUETY_STALE_TIMEOUT secondes. Une tâche obsolète ayant encore des tentatives disponibles est réessayée après le délai de temporisation ; si toutes ses tentatives ont été utilisées, elle est mise en attente et son workflow est marqué comme ayant échoué. Les workers --once et la solution de repli WP-Cron n’effectuent pas cette vérification.

Récupérez manuellement les tâches obsolètes :

Shell
wp queuety recover

Mode de vidage

Traitez toutes les tâches en attente, puis quittez le processus. Pratique pour les tests ou le traitement ponctuel par lots :

Shell
wp queuety flush
wp queuety flush --queue=emails

Déploiement en production

En production, utilisez un gestionnaire de processus pour maintenir les workers en fonctionnement. Voici deux approches courantes.

Supervisord

Ini
[program:queuety-default]
command=wp queuety work --queue=default
directory=/var/www/html
autostart=true
autorestart=true
numprocs=2
process_name=%(program_name)s_%(process_num)02d
stdout_logfile=/var/log/queuety-default.log
stderr_logfile=/var/log/queuety-default-error.log

[program:queuety-emails]
command=wp queuety work --queue=emails
directory=/var/www/html
autostart=true
autorestart=true
numprocs=1
stdout_logfile=/var/log/queuety-emails.log
stderr_logfile=/var/log/queuety-emails-error.log

Systemd

Ini
[Unit]
Description=Queuety Worker (default queue)
After=mysql.service

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/html
ExecStart=/usr/local/bin/wp queuety work --queue=default
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Activez et démarrez :

Shell
sudo systemctl enable queuety-worker
sudo systemctl start queuety-worker

Conseils de déploiement

Lancez des workers distincts pour chaque file lorsque vous avez besoin d’une isolation renforcée. Utilisez --workers=N pour les charges de travail limitées par le processeur et privilégiez les workers supervisés individuellement lorsque la charge repose principalement sur les entrées-sorties. Définissez QUEUETY_WORKER_MAX_JOBS si vous souhaitez des redémarrages périodiques pour libérer de la mémoire, et surveillez le nombre de buried dans webhooks ou métriques.