
# Traitement par lots

Les lots vous permettent de déclencher un groupe de tâches et de le suivre comme une seule unité. Vous pouvez enregistrer des callbacks qui se déclenchent lorsque le lot est terminé, lorsqu’une tâche échoue ou lorsque le lot se termine quel que soit le résultat. Queuety suit automatiquement la progression, les échecs et l’état d’annulation.

## Créer un lot

Utilisez `Queuety::create_batch()` pour démarrer un `BatchBuilder`. Transmettez un tableau d’instances `Contracts\Job`, puis appelez `dispatch()` pour créer l’entrée du lot et toutes les tâches.

```php
use Queuety\Queuety;

$batch = Queuety::create_batch( [
    new ImportUsersJob( $csv_chunk_1 ),
    new ImportUsersJob( $csv_chunk_2 ),
    new ImportUsersJob( $csv_chunk_3 ),
] )
    ->name( 'Import users' )
    ->on_queue( 'imports' )
    ->dispatch();

echo $batch->id; // The batch ID
```

`dispatch()` renvoie un objet valeur `Batch` contenant l’état du lot.

Vous pouvez également transmettre des tableaux gestionnaire + charge utile à la place des instances de tâche :

```php
$batch = Queuety::create_batch( [
    [ 'handler' => 'import_users', 'payload' => [ 'chunk' => 1 ] ],
    [ 'handler' => 'import_users', 'payload' => [ 'chunk' => 2 ] ],
] )->dispatch();
```

## Callbacks

Enregistrez des classes de gestionnaire à appeler à différentes étapes du cycle de vie du lot. Chaque classe de gestionnaire doit avoir une méthode `handle( Batch $batch )`.

```php
$batch = Queuety::create_batch( $jobs )
    ->name( 'Import users' )
    ->then( ImportCompleteHandler::class )
    ->catch( ImportFailedHandler::class )
    ->finally( ImportCleanupHandler::class )
    ->dispatch();
```

| Méthode | Déclenchement |
|---|---|
| `then( $handler_class )` | Toutes les tâches sont terminées avec succès (ou `allow_failures()` est défini) |
| `catch( $handler_class )` | La première tâche du lot échoue |
| `finally( $handler_class )` | Le lot se termine, qu’il ait réussi ou échoué |

### Écrire un gestionnaire de callback

```php
use Queuety\Batch;

class ImportCompleteHandler {
    public function handle( Batch $batch ): void {
        // All users imported. Send a notification.
        error_log( "Batch {$batch->id} completed: {$batch->total_jobs} jobs processed." );
    }
}

class ImportFailedHandler {
    public function handle( Batch $batch ): void {
        error_log( "Batch {$batch->id} had a failure. Failed jobs: {$batch->failed_jobs}" );
    }
}

class ImportCleanupHandler {
    public function handle( Batch $batch ): void {
        // Runs regardless of outcome. Clean up temp files, etc.
    }
}
```

## Autoriser les échecs

Par défaut, le callback `then` ne se déclenche que si toutes les tâches du lot réussissent. Appelez `allow_failures()` pour autoriser le déclenchement du callback `then` même en cas d’échec de certaines tâches.

```php
$batch = Queuety::create_batch( $jobs )
    ->then( ReportHandler::class )
    ->allow_failures()
    ->dispatch();
```

## Suivi de la progression

L’objet valeur `Batch` fournit des propriétés et des méthodes pour suivre la progression.

```php
$batch = Queuety::find_batch( $batch_id );

$batch->progress();      // 0-100 percentage
$batch->finished();      // true if all jobs are done
$batch->has_failures();  // true if any job failed
$batch->cancelled();     // true if the batch was cancelled

$batch->total_jobs;      // Total number of jobs
$batch->pending_jobs;    // Jobs still pending
$batch->failed_jobs;     // Number of failed jobs
$batch->failed_job_ids;  // Array of failed job IDs
```

| Méthode/Propriété | Type | Description |
|---|---|---|
| `progress()` | `int` | Pourcentage d’achèvement de 0 à 100 |
| `finished()` | `bool` | Indique si le lot est terminé (toutes les tâches sont achevées ou ont échoué) |
| `has_failures()` | `bool` | Indique si des tâches du lot ont échoué |
| `cancelled()` | `bool` | Indique si le lot a été annulé |
| `$total_jobs` | `int` | Nombre total de tâches du lot |
| `$pending_jobs` | `int` | Nombre de tâches encore en attente |
| `$failed_jobs` | `int` | Nombre de tâches ayant échoué |
| `$failed_job_ids` | `array` | ID des tâches ayant échoué |
| `$name` | `string\|null` | Nom facultatif du lot |
| `$created_at` | `DateTimeImmutable` | Date de création du lot |
| `$finished_at` | `DateTimeImmutable\|null` | Date de fin du lot |
| `$cancelled_at` | `DateTimeImmutable\|null` | Date d’annulation du lot |

## Annulation

Annulez un lot via le `BatchManager`. L’annulation d’un lot définit `cancelled_at` et `finished_at`, puis déclenche le callback `finally`.

```php
Queuety::batch_manager()->cancel( $batch_id );
```

L’annulation marque le lot comme annulé et terminé, puis déclenche son callback `finally`. Elle ne touche pas aux tâches : celles en attente dans un lot annulé s’exécutent quand même, mais leurs résultats ne mettent plus à jour les compteurs du lot et ne déclenchent plus `then`, `catch` ou `finally`. Supprimez vous-même les tâches si elles ne doivent pas s’exécuter.

## Rechercher des lots

Recherchez un lot par son ID :

```php
$batch = Queuety::find_batch( $batch_id );

if ( null === $batch ) {
    // Batch not found.
}
```

## Supprimer les anciens lots

Supprimez les lots terminés depuis plus d’un nombre donné de jours :

```php
$deleted = Queuety::batch_manager()->prune( 30 ); // Delete batches finished > 30 days ago
```

Seuls les lots dont l’horodatage `finished_at` n’est pas nul sont supprimés. Les lots actifs ne sont jamais purgés.
