
# Introduction

Queuety est un plugin WordPress qui fournit une file de tâches rapide, un moteur de workflow durable et un moteur d'exécution de machines à états durables. Les workers récupèrent directement les tâches depuis MySQL et les traitent dans un processus WP-CLI de longue durée. L'environnement d'exécution PHP qui charge WordPress et WP-CLI nécessite `mysqli` ou `pdo_mysql`.

## Pourquoi Queuety ?

WordPress ne dispose pas d'un véritable système de tâches en arrière-plan. `wp_cron` ne se déclenche que lors des visites de pages. Le lanceur par défaut d'Action Scheduler s'appuie sur WP-Cron et sur des requêtes HTTP de bouclage, en traitant chaque fois des lots pendant 30 secondes maximum. Un appel API à un LLM qui prend 60 secondes est interrompu par le délai d'expiration de 30 secondes de PHP. Il est impossible d'exécuter des processus en plusieurs étapes qui survivent aux pannes et reprennent là où ils se sont arrêtés.

Queuety résout ce problème grâce à trois primitives :

1. **Tâches** pour le traitement en arrière-plan sans suivi
2. **Workflows** pour les processus durables en plusieurs étapes avec état persistant
3. **Machines à états** pour les cycles de vie durables, pilotés par événements

## Exemple rapide

Déclenchez une tâche avec la classe moderne API :

```php
use Queuety\Contracts\Job;
use Queuety\Dispatchable;

readonly class SendEmailJob implements Job {
    use Dispatchable;

    public function __construct(
        public string $to,
        public string $subject,
        public string $body,
    ) {}

    public function handle(): void {
        wp_mail( $this->to, $this->subject, $this->body );
    }
}

SendEmailJob::dispatch( 'user@example.com', 'Welcome', 'Hello from Queuety!' );
```

Vous pouvez aussi utiliser l'approche classique avec le nom du gestionnaire :

```php
use Queuety\Queuety;

Queuety::dispatch( 'send_email', [ 'to' => 'user@example.com' ] );
```

Exécutez un workflow durable :

```php
Queuety::workflow( 'generate_report' )
    ->then( FetchDataHandler::class )
    ->then( CallLLMHandler::class )
    ->then( FormatOutputHandler::class )
    ->dispatch( [ 'user_id' => 42 ] );
```

Modélisez une session de longue durée avec une machine à états :

```php
use Queuety\Enums\StateMachineStatus;

Queuety::machine( 'agent_session' )
    ->state( 'awaiting_user' )
    ->on( 'user_message', 'planning' )
    ->state( 'planning' )
    ->action( PlanSessionAction::class )
    ->on( 'planned', 'completed' )
    ->state( 'completed', StateMachineStatus::Completed )
    ->dispatch( [ 'thread_id' => 42 ] );
```

Démarrez un worker :

```bash
wp queuety work
```

Si vous créez un système de type agent, commencez par [Orchestration d'agents](https://queuety.inline0.dev/fr/docs/workflows/agent-orchestration). Vous y découvrirez comment s'articulent les flux planificateur/exécuteur, les étapes de validation humaine et les attentes entre workflows.

Si votre système est piloté par événements et de longue durée, commencez par [Machines à états](https://queuety.inline0.dev/fr/docs/state-machines), en complément des workflows.

Pour des exemples d'intégration de bout en bout, consultez [Exemples](https://queuety.inline0.dev/fr/docs/examples), qui incluent désormais des modèles basés sur Neuron pour le changement de fournisseur, la diffusion, les nouvelles tentatives de validation avec mémoire et les workflows dépendants.

Pour déclencher des workflows à partir d'événements de domaine WordPress tels que `save_post`, consultez [Déclencheurs d'action](https://queuety.inline0.dev/fr/docs/features/action-triggers).

Pour utiliser l'environnement d'exécution adossé à une base de données en dehors de WordPress, consultez [Utilisation autonome](https://queuety.inline0.dev/fr/docs/features/standalone-use).

## Principales différences

- **Exécution rapide.** Les workers accèdent directement à la file MySQL et évitent le modèle cron par requête qui ralentit le traitement en arrière-plan dans WordPress.
- **Workflows durables.** Les processus en plusieurs étapes avec état persistant résistent aux délais d'expiration PHP, aux pannes et aux nouvelles tentatives. Chaque limite d'étape correspond à une transaction atomique MySQL.
- **Machines à états explicites.** Modélisez les sessions de discussion, les approbations et autres cycles de vie de longue durée avec des états nommés, des transitions protégées, des actions en file d'attente à l'entrée d'un état et des chronologies d'événements durables.
- **Tâches modernes déclenchables API.** Classes de tâches autonomes avec le trait `Dispatchable`, des propriétés de constructeur typées comme données utiles et les éléments `$tries`/`$timeout`/`$backoff` déclarés sur la classe. Une classe `readonly` ne peut pas attribuer de valeurs par défaut à ces propriétés ; déclarez-les donc dans une classe ordinaire avec des propriétés promues en lecture seule dans le constructeur.
- **Pipeline de middleware.** Middleware en couches pour limiter le débit, limiter les exceptions, garantir l'unicité des tâches et ajouter une logique personnalisée. Déclaré pour chaque tâche via une méthode `middleware()`.
- **Étapes de diffusion.** L'interface `StreamingStep` produit des fragments qui sont immédiatement enregistrés dans la base de données. En cas de nouvelle tentative, les fragments déjà enregistrés sont fournis afin que la diffusion reprenne là où elle s'était arrêtée. Idéal pour les réponses des LLM et les téléchargements volumineux.
- **Couche de cache enfichable.** `CacheFactory` détecte automatiquement APCu ou utilise un cache en mémoire. Les systèmes de stockage personnalisés implémentent `Contracts\Cache`. Cette couche sert en interne aux recherches du limiteur de débit et à l'état des files.
- **Traitement par lots et chaînage.** Déclenchez des groupes de tâches avec les fonctions de rappel `then`/`catch`/`finally` et le suivi de progression, ou enchaînez les tâches séquentiellement, chacune dépendant de l'achèvement de la précédente.
- **Délais et attentes durables.** `delay()` ajoute des délais sûrs en cas de redémarrage du processus. `wait_for_signal()`, `wait_for_signals()`, `wait_for_approval()`, `wait_for_input()` et `wait_for_workflow()` permettent aux workflows d'attendre des événements externes ou d'autres workflows sans maintenir PHP en vie.
- **Boucle dynamique.** `for_each()` développe les branches détectées à l'exécution à partir de l'état du workflow et prend en charge les modes d'achèvement « tous réussis », « premier succès » et « quorum ».
- **Transferts asynchrones entre workflows.** `start_workflows()` transforme les éléments détectés à l'exécution en workflows indépendants de premier niveau, auxquels il est possible d'attendre ultérieurement.
- **Déclencheurs d'action WordPress.** `on_action()` associe les hooks d'action du cœur ou des plugins au déclenchement de workflows durables, avec contrôle préalable et idempotence.
- **Artefacts durables.** Stockez les résultats nommés des workflows en dehors du conteneur d'état principal et conservez-les lors de l'inspection de l'état, CLI, de l'exportation et de la relecture.
- **Garde-fous des workflows.** `version()`, une empreinte déterministe de définition, des clés de déclenchement idempotentes et des budgets de workflow facilitent l'inspection des exécutions de type agent et limitent les doublons ou les dérives silencieuses.
- **Gestion des ressources.** Les groupes de concurrence, les unités de coût, les budgets de workflow et l'admission des workers aident à maintenir les traitements coûteux de type agent dans des limites définies.
- **Compensation des étapes.** `compensate_with()` et `compensate_on_failure()` fournissent des hooks de restauration pour les étapes terminées lorsque les workflows sont annulés ou échouent.
- **Signaux d'activité.** Les étapes de longue durée envoient des signaux pour empêcher le système de récupération des tâches obsolètes de reprendre un travail en cours.
- **Traçage des workflows.** Chaque transition d'étape est enregistrée avec les entrées, les sorties, l'état avant et après, le contexte, les artefacts, les fragments, les erreurs et le débogage temporel via `workflow_state_at()`.
- **Étapes parallèles.** Exécutez les étapes simultanément et attendez leur achèvement à toutes avant de poursuivre.
- **Branchement conditionnel.** Passez à des étapes nommées selon l'état précédent avec `_next_step`.
- **Exécution de workflows.** Démarrez des workflows enfants qui renvoient leurs résultats au parent.
- **Files à priorité.** Quatre niveaux (faible, normal, élevé, urgent) via les énumérations à typage sûr PHP.
- **Workers à files multiples.** Traitez plusieurs files avec un ordre de priorité strict dans un seul worker.
- **Limitation de débit.** Limites d'exécution par gestionnaire avec fenêtre glissante.
- **Tâches récurrentes.** Planification par intervalle et selon cron, avec politiques de chevauchement configurables (autoriser, ignorer, mettre en tampon).
- **Annulation des workflows.** Annulez les workflows en cours et déclenchez les gestionnaires de nettoyage enregistrés.
- **Élagage de l'état.** Supprimez automatiquement les anciennes sorties d'étapes pour gérer les états volumineux des workflows.
- **Concurrence des workers.** `--workers=N` lance plusieurs processus et les redémarre automatiquement en cas de panne.
- **Observabilité complète.** Journalisation dans la base de données, métriques par gestionnaire et webhooks d'événements.
- **Outils de test.** `QueueFake` enregistre les tâches et les lots déclenchés pour les assertions des tests unitaires.
- **Attributs PHP.** `#[QueuetyHandler('name')]` pour enregistrer les gestionnaires sans configuration.

## Fonctionnement

Les workers s'exécutent dans un processus WP-CLI de longue durée et récupèrent directement les tâches depuis MySQL. Les lignes de file d'attente, l'état des workflows, les journaux, les lots, les signaux et les fragments diffusés résident tous dans MySQL ; les redémarrages des workers ne font donc pas perdre l'état de l'orchestration.

Les workflows décomposent les traitements de longue durée en étapes. Chaque étape enregistre sa sortie dans un conteneur d'état partagé dans la base de données. Si PHP s'arrête au milieu d'une étape, le worker réessaie cette étape avec tout l'état antérieur intact. La limite de l'étape correspond à une transaction unique MySQL : la mise à jour de l'état, la fin de la tâche et la mise en file de l'étape suivante ont lieu de manière atomique.

```
Workflow: generate_report (3 steps)

Step 0: fetch_data     -> state: {user_data: {...}}
Step 1: call_llm       -> PHP dies -> retry -> state: {user_data: {...}, llm_response: "..."}
Step 2: format_output  -> state: {user_data: {...}, llm_response: "...", report_url: "/reports/42.pdf"}

Workflow: completed
```

## Prérequis

- PHP 8.2 ou version ultérieure
- WordPress 6.4 ou version ultérieure
- MySQL 8.0+ ou MariaDB 10.6+, car les workers récupèrent les tâches avec `SELECT ... FOR UPDATE SKIP LOCKED`
- `mysqli` ou `pdo_mysql` dans l'environnement d'exécution PHP qui charge WordPress et WP-CLI
- WP-CLI pour exécuter des workers dédiés avec `wp queuety work`
- Les extensions `pcntl` et `posix` PHP pour les pools de workers (`--workers`, `--min-workers`, `--max-workers`)

Consultez [Bien démarrer](https://queuety.inline0.dev/fr/docs/getting-started) pour l'installation.
