
# Premiers pas

## Installation

### Prérequis

- PHP 8.2 ou ultérieur et WordPress 6.4 ou ultérieur
- MySQL 8.0+ ou MariaDB 10.6+. Les workers revendiquent des tâches et des planifications arrivées à échéance avec `SELECT ... FOR UPDATE SKIP LOCKED`, que les serveurs plus anciens rejettent avec une erreur de syntaxe.
- `mysqli` ou `pdo_mysql` (voir ci-dessous)
- WP-CLI sur le serveur si vous utilisez des workers dédiés avec `wp queuety work`
- Les extensions PHP `pcntl` et `posix` si vous utilisez des pools de workers avec `--workers` ou `--min-workers`/`--max-workers`

Queuety nécessite `mysqli` ou `pdo_mysql` dans l’environnement d’exécution PHP qui charge WordPress et WP-CLI. Le pilote est choisi automatiquement : `mysqli` est privilégié dans les environnements WordPress, tandis que `pdo_mysql` reste disponible pour une utilisation autonome ou directe de l’environnement d’exécution.

Pour utiliser l’environnement d’exécution adossé à la base de données sans la couche d’extension WordPress, consultez [Utilisation autonome](https://queuety.inline0.dev/fr/docs/features/standalone-use). Cette méthode utilise la même connexion et les mêmes tables d’exécution, mais n’inclut pas les ponts de hooks WordPress ni l’enregistrement WP-CLI.

### Depuis l’archive de version

Chaque [versionGitHub de ](https://github.com/inline0/queuety/releases) comprend un fichier `queuety.zip` : l’extension avec ses dépendances Composer déjà installées. Installez la dernière version avec WP-CLI :

```bash
wp plugin install https://github.com/inline0/queuety/releases/latest/download/queuety.zip --activate
```

Vous pouvez aussi télécharger l’archive zip et la téléverser dans Extensions > Ajouter une extension > Téléverser une extension. C’est la méthode la plus simple pour un site WordPress classique.

### Via Composer pour les Composer gérés par WordPress

```bash
composer require queuety/queuety
```

Activez ensuite l’extension :

```bash
wp plugin activate queuety
```

Le type de paquet est `wordpress-plugin`. Composer le place dans votre répertoire de plugins uniquement lorsque le projet requiert `composer/installers` et associe ce type à un chemin d'installation, comme le fait Bedrock, et le projet doit charger son propre `vendor/autoload.php` (Bedrock le fait également). Sans `composer/installers`, Composer l'installe dans `vendor/queuety/queuety`, où WordPress ne le trouve pas ; utilisez donc l'archive zip de la version sur une installation WordPress standard.

### Depuis les sources pendant le développement

Placez le dépôt dans `wp-content/plugins/queuety`, puis installez les dépendances PHP :

```bash
composer install
wp plugin activate queuety
```

À l'activation, Queuety crée ses tables de base de données (`queuety_jobs`, `queuety_workflows`, `queuety_logs`, `queuety_schedules`, `queuety_queue_states`, `queuety_webhooks`, `queuety_locks`, `queuety_signals`, `queuety_workflow_dependencies`, `queuety_workflow_dispatch_keys`, `queuety_batches`, `queuety_chunks`, `queuety_workflow_events`, `queuety_artifacts`, `queuety_state_machines`, `queuety_state_machine_events`), afin que les workers puissent récupérer directement les tâches depuis MySQL.

Par défaut, le plugin planifie également un worker ponctuel via WordPress cron chaque minute pour la file d'attente `default`. Cela fournit une solution de base sans shell pour les tâches et workflows qui restent sur `default`, à condition que WordPress cron se déclenche. Chaque exécution traite au plus une tâche ; elle ne déclenche pas les planifications récurrentes, ne récupère pas les tâches obsolètes et ne vérifie pas les échéances des workflows ; ces opérations ne s'exécutent que dans un processus `wp queuety work` de longue durée ([#14](https://github.com/inline0/queuety/issues/14)). Pour les files personnalisées, les planifications récurrentes, une latence plus faible ou des charges plus importantes, passez à des processus `wp queuety work` dédiés.

## Configuration

Toutes les constantes sont facultatives. Définissez-les dans `wp-config.php` avant le chargement du plugin, ou avant le démarrage de Queuety dans une installation intégrée de type thème :

| Constante | Valeur par défaut | Description |
|---|---|---|
| `QUEUETY_RETENTION_DAYS` | `7` | Âge par défaut en jours pour `wp queuety purge` et `Queuety::purge()`. Rien n'est purgé automatiquement |
| `QUEUETY_LOG_RETENTION_DAYS` | `0` | Lue par `Config::log_retention_days()`, mais pas encore utilisée ; les journaux sont conservés jusqu'à l'appel de `Queuety::purge_logs()` ([#15](https://github.com/inline0/queuety/issues/15)) |
| `QUEUETY_MAX_EXECUTION_TIME` | `300` | Durée maximale en secondes par tâche avant expiration (pas encore appliquée, voir [Tâches](https://queuety.inline0.dev/fr/docs/jobs#timeout)) |
| `QUEUETY_WORKER_SLEEP` | `1` | Durée d'attente en secondes lorsque la file est vide |
| `QUEUETY_WORKER_MAX_JOBS` | `1000` | Nombre maximal de tâches avant le redémarrage du worker |
| `QUEUETY_WORKER_MAX_MEMORY` | `128` | Nombre maximal de Mo avant le redémarrage du worker |
| `QUEUETY_RETRY_BACKOFF` | `exponential` | Stratégie de délai progressif : `exponential`, `linear` ou `fixed` |
| `QUEUETY_STALE_TIMEOUT` | `600` | Délai en secondes avant la récupération des tâches bloquées |
| `QUEUETY_CACHE_TTL` | `5` | Durée de vie du cache par défaut, en secondes |
| `QUEUETY_DEBUG` | `false` | Activer la journalisation détaillée du worker |
| `QUEUETY_CLI_COMMAND` | `queuety` | Nom de la commande racine WP-CLI |
| `QUEUETY_TABLE_PREFIX` | `queuety_` | Nom de base commun à toutes les tables Queuety après le préfixe de base de données WordPress |
| `QUEUETY_TABLE_JOBS` | `queuety_jobs` | Nom de la table des tâches |
| `QUEUETY_TABLE_WORKFLOWS` | `queuety_workflows` | Nom de la table des workflows |
| `QUEUETY_TABLE_LOGS` | `queuety_logs` | Nom de la table des journaux |
| `QUEUETY_TABLE_SCHEDULES` | `queuety_schedules` | Nom de la table des planifications |
| `QUEUETY_TABLE_SIGNALS` | `queuety_signals` | Nom de la table des signaux |
| `QUEUETY_TABLE_WORKFLOW_DEPENDENCIES` | `queuety_workflow_dependencies` | Nom de la table d'attente des dépendances de workflow |
| `QUEUETY_TABLE_WORKFLOW_DISPATCH_KEYS` | `queuety_workflow_dispatch_keys` | Nom de la table d'idempotence des workflows durables |
| `QUEUETY_TABLE_CHUNKS` | `queuety_chunks` | Nom de la table des fragments diffusés |
| `QUEUETY_TABLE_QUEUE_STATES` | `queuety_queue_states` | Nom de la table des états de file d'attente |
| `QUEUETY_TABLE_WEBHOOKS` | `queuety_webhooks` | Nom de la table des webhooks |
| `QUEUETY_TABLE_LOCKS` | `queuety_locks` | Nom de la table des verrous |
| `QUEUETY_TABLE_BATCHES` | `queuety_batches` | Nom de la table des lots |
| `QUEUETY_TABLE_WORKFLOW_EVENTS` | `queuety_workflow_events` | Nom de la table du journal d'événements des workflows |
| `QUEUETY_TABLE_ARTIFACTS` | `queuety_artifacts` | Nom de la table des artefacts de workflow |
| `QUEUETY_TABLE_STATE_MACHINES` | `queuety_state_machines` | Nom de la table des machines à états |
| `QUEUETY_TABLE_STATE_MACHINE_EVENTS` | `queuety_state_machine_events` | Nom de la table du journal d'événements des machines à états |
| `QUEUETY_DB_DRIVER` | `auto` | Pilote MySQL : `auto`, `mysqli` ou `pdo`. `auto` privilégie `mysqli` lorsque WordPress est chargé ; sinon `pdo_mysql`, puis `mysqli` |

Les constantes d'admission des ressources et du pool adaptatif (`QUEUETY_RESOURCE_*`, `QUEUETY_WORKER_POOL_*`) sont répertoriées sur la page [Workers](https://queuety.inline0.dev/fr/docs/features/workers).

`QUEUETY_TABLE_PREFIX` ne modifie que la partie Queuety des noms de tables. Le préfixe de base de données WordPress s'ajoute toujours au résultat ; ainsi, `$wpdb->prefix = 'wp_'` et `QUEUETY_TABLE_PREFIX = 'themequeue_'` produisent des tables telles que `wp_themequeue_jobs`. Les constantes `QUEUETY_TABLE_*` explicites restent prioritaires pour les tables individuelles.

Les connexions autonomes peuvent également définir le préfixe de table Queuety par connexion :

```php
$conn = new Connection(
    host: '127.0.0.1:3306',
    dbname: 'wordpress',
    user: 'root',
    password: 'secret',
    prefix: 'wp_',
    table_prefix: 'themequeue_',
);
```

Le préfixe de base de données WordPress reste ainsi intact et seule la partie Queuety de la table est modifiée.

## Votre première tâche

Créez une classe de gestionnaire qui implémente l'interface `Handler` :

```php
use Queuety\Handler;

class SendEmailHandler implements Handler {
    public function handle( array $payload ): void {
        wp_mail( $payload['to'], $payload['subject'], $payload['body'] );
    }

    public function config(): array {
        return [
            'queue'           => 'emails',
            'max_attempts'    => 5,
        ];
    }
}
```

Enregistrez-la et déclenchez son exécution :

```php
use Queuety\Queuety;

Queuety::register( 'send_email', SendEmailHandler::class );

Queuety::dispatch( 'send_email', [
    'to'      => 'user@example.com',
    'subject' => 'Welcome',
    'body'    => 'Hello from Queuety!',
] );
```

Vous pouvez aussi utiliser la classe de tâche moderne qui peut être déclenchée :

```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!' );
```

## Votre premier workflow

Définissez des gestionnaires d'étapes qui implémentent l'interface `Step` :

```php
use Queuety\Step;

class FetchDataHandler implements Step {
    public function handle( array $state ): array {
        $user = get_user_by( 'ID', $state['user_id'] );
        return [ 'user_name' => $user->display_name ];
    }

    public function config(): array {
        return [];
    }
}

class CallLLMHandler implements Step {
    public function handle( array $state ): array {
        $response = wp_remote_post( 'https://api.openai.com/v1/chat/completions', [
            'body' => json_encode( [ 'prompt' => "Generate report for {$state['user_name']}" ] ),
        ] );
        return [ 'llm_response' => wp_remote_retrieve_body( $response ) ];
    }

    public function config(): array {
        return [ 'max_attempts' => 5 ];
    }
}

class FormatOutputHandler implements Step {
    public function handle( array $state ): array {
        $url = save_report( $state['user_name'], $state['llm_response'] );
        return [ 'report_url' => $url ];
    }

    public function config(): array {
        return [];
    }
}
```

Déclenchez le workflow :

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

## Démarrer un worker

```bash
wp queuety work
```

Le worker recherche les tâches en attente, les exécute, fait avancer les workflows et se met en veille lorsque la file est vide. Appuyez sur `Ctrl+C` pour l'arrêter ; le processus se termine immédiatement, même en pleine exécution d'une tâche (voir [Workers](https://queuety.inline0.dev/fr/docs/features/workers#worker-lifecycle)).

Le `SendEmailHandler` ci-dessus envoie ses tâches à la file `emails` via `config()` ; un worker sur `default` ne les récupère donc pas. Nommez chaque file que vous utilisez :

```bash
wp queuety work --queue=emails,default
```

Si vous n'exécutez pas de worker dédié, Queuety conserve la solution de repli WordPress cron par défaut, déclenchée une fois par minute et décrite ci-dessus ; elle est limitée à la file `default` et à une tâche par exécution. Le worker dédié offre un débit supérieur et une latence plus faible.

En production, exécutez plusieurs workers :

```bash
wp queuety work --workers=4
```

Traitez plusieurs files avec un ordre de priorité :

```bash
wp queuety work --queue=high,default,low
```

## Étapes suivantes

- [Tâches](https://queuety.inline0.dev/fr/docs/jobs) pour le guide complet sur le déclenchement et la gestion des tâches
- [Workflows](https://queuety.inline0.dev/fr/docs/workflows) pour les enchaînements, les étapes parallèles, les branchements conditionnels et l'exécution de workflows
- [Middleware](https://queuety.inline0.dev/fr/docs/features/middleware) pour la limitation de débit, le throttling et la logique personnalisée du pipeline
- [Traitement par lots](https://queuety.inline0.dev/fr/docs/features/batching) pour déclencher des groupes de tâches avec des fonctions de rappel
- [Étapes de diffusion](https://queuety.inline0.dev/fr/docs/workflows/streaming) pour enregistrer les données diffusées fragment par fragment
- [Planification](https://queuety.inline0.dev/fr/docs/features/scheduling) pour les tâches récurrentes
- [Mise en cache](https://queuety.inline0.dev/fr/docs/features/caching) pour la couche de cache enfichable
- [Tests](https://queuety.inline0.dev/fr/docs/features/testing) pour QueueFake et les assertions de test
- [RéférenceCLI](https://queuety.inline0.dev/fr/docs/cli) pour toutes les commandes disponibles
- [PHP API](https://queuety.inline0.dev/fr/docs/api) pour l'accès programmatique
