
# Grupare în loturi

Loturile vă permit să trimiteți un grup de activități și să le urmăriți ca pe o singură unitate. Puteți înregistra callback-uri care se declanșează când lotul este complet, când eșuează orice activitate sau când lotul se încheie indiferent de rezultat. Queuety urmărește automat progresul, eșecurile și starea anulării.

## Crearea unui lot

Folosiți `Queuety::create_batch()` pentru a începe un `BatchBuilder`. Pasați un array de instanțe `Contracts\Job`, apoi apelați `dispatch()` pentru a crea rândul lotului și toate activitățile.

```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()` returnează un obiect valoare `Batch` cu starea lotului.

Puteți pasa și array-uri handler+payload în locul instanțelor de activități:

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

## Callback-uri

Înregistrați clasele handler care vor fi apelate în diferite momente ale ciclului de viață al lotului. Fiecare clasă handler trebuie să aibă o metodă `handle( Batch $batch )`.

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

| Metodă | Când se declanșează |
|---|---|
| `then( $handler_class )` | Toate activitățile s-au încheiat cu succes (sau este setat `allow_failures()`) |
| `catch( $handler_class )` | Prima activitate din lot eșuează |
| `finally( $handler_class )` | Lotul se încheie, indiferent dacă a reușit sau a eșuat |

### Scrierea unui handler 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.
    }
}
```

## Permiterea eșecurilor

În mod implicit, callback-ul `then` se declanșează doar dacă toate activitățile din lot reușesc. Apelați `allow_failures()` pentru ca callback-ul `then` să se declanșeze chiar dacă unele activități eșuează.

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

## Urmărirea progresului

Obiectul valoare `Batch` oferă proprietăți și metode pentru urmărirea progresului.

```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
```

| Metodă/proprietate | Tip | Descriere |
|---|---|---|
| `progress()` | `int` | Procentul de finalizare, de la 0 la 100 |
| `finished()` | `bool` | Indică dacă lotul s-a încheiat (toate activitățile s-au finalizat sau au eșuat) |
| `has_failures()` | `bool` | Indică dacă au eșuat activități din lot |
| `cancelled()` | `bool` | Indică dacă lotul a fost anulat |
| `$total_jobs` | `int` | Numărul total de activități din lot |
| `$pending_jobs` | `int` | Numărul de activități încă în așteptare |
| `$failed_jobs` | `int` | Numărul de activități eșuate |
| `$failed_job_ids` | `array` | ID-urile activităților eșuate |
| `$name` | `string\|null` | Numele opțional al lotului |
| `$created_at` | `DateTimeImmutable` | Momentul creării lotului |
| `$finished_at` | `DateTimeImmutable\|null` | Momentul încheierii lotului |
| `$cancelled_at` | `DateTimeImmutable\|null` | Momentul anulării lotului |

## Anulare

Anulați un lot prin `BatchManager`. Anularea unui lot setează `cancelled_at` și `finished_at` și declanșează callback-ul `finally`.

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

Anularea marchează lotul ca anulat și încheiat și declanșează callback-ul său `finally`. Nu afectează activitățile: cele în așteptare dintr-un lot anulat rulează în continuare, dar rezultatele lor nu mai actualizează contoarele lotului și nu mai declanșează `then`, `catch` sau `finally`. Ștergeți manual activitățile dacă nu trebuie să ruleze.

## Găsirea loturilor

Căutați un lot după ID:

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

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

## Eliminarea loturilor vechi

Eliminați loturile încheiate cu mai mult decât numărul de zile specificat în urmă:

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

Se șterg doar loturile care au un marcaj temporal `finished_at` nenul. Loturile active nu sunt eliminate niciodată.
