
# المعالجة على دفعات

تتيح لك الدفعات إرسال مجموعة من المهام وتتبعها كوحدة واحدة. يمكنك تسجيل عمليات استدعاء تُنفّذ عند اكتمال الدفعة، أو فشل أي مهمة، أو انتهاء الدفعة أيًا كانت النتيجة. يتتبع Queuety التقدم والإخفاقات وحالة الإلغاء تلقائيًا.

## إنشاء دفعة

استخدم `Queuety::create_batch()` لبدء `BatchBuilder`. مرّر مصفوفة من مثيلات `Contracts\Job`، ثم استدعِ `dispatch()` لإنشاء سجل الدفعة وجميع المهام.

```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()` كائن قيمة من النوع `Batch` يتضمن حالة الدفعة.

يمكنك أيضًا تمرير مصفوفات تتضمن المعالج والحمولة بدلًا من مثيلات المهام:

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

## عمليات الاستدعاء

سجّل فئات المعالجات التي ستُستدعى في نقاط مختلفة من دورة حياة الدفعة. يجب أن تتضمن كل فئة معالج طريقة `handle( Batch $batch )`.

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

| الطريقة | توقيت التنفيذ |
|---|---|
| `then( $handler_class )` | عند اكتمال جميع المهام بنجاح (أو تعيين `allow_failures()`) |
| `catch( $handler_class )` | عند فشل أول مهمة في الدفعة |
| `finally( $handler_class )` | عند انتهاء الدفعة، سواء نجحت أم فشلت |

### كتابة معالج لعملية استدعاء

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

## السماح بالإخفاقات

افتراضيًا، لا تُنفّذ عملية الاستدعاء `then` إلا إذا نجحت جميع مهام الدفعة. استدعِ `allow_failures()` للسماح بتنفيذ عملية الاستدعاء `then` حتى عند فشل بعض المهام.

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

## تتبع التقدم

يوفر كائن القيمة `Batch` خصائص وطرقًا لتتبع التقدم.

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

| الطريقة/الخاصية | النوع | الوصف |
|---|---|---|
| `progress()` | `int` | نسبة الاكتمال من 0 إلى 100 |
| `finished()` | `bool` | ما إذا كانت الدفعة قد انتهت (اكتملت جميع المهام أو فشلت) |
| `has_failures()` | `bool` | ما إذا كانت أي مهام في الدفعة قد فشلت |
| `cancelled()` | `bool` | ما إذا أُلغيت الدفعة |
| `$total_jobs` | `int` | إجمالي عدد المهام في الدفعة |
| `$pending_jobs` | `int` | عدد المهام التي لا تزال معلّقة |
| `$failed_jobs` | `int` | عدد المهام الفاشلة |
| `$failed_job_ids` | `array` | معرّفات المهام التي فشلت |
| `$name` | `string\|null` | اسم الدفعة، إن وُجد |
| `$created_at` | `DateTimeImmutable` | وقت إنشاء الدفعة |
| `$finished_at` | `DateTimeImmutable\|null` | وقت انتهاء الدفعة |
| `$cancelled_at` | `DateTimeImmutable\|null` | وقت إلغاء الدفعة |

## الإلغاء

ألغِ دفعة عبر `BatchManager`. يؤدي إلغاء الدفعة إلى تعيين `cancelled_at` و`finished_at`، كما ينفّذ عملية الاستدعاء `finally`.

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

يضع الإلغاء علامة على الدفعة بأنها ملغاة ومنتهية، وينفّذ عملية الاستدعاء `finally`. ولا يمس المهام: إذ تستمر المهام المعلّقة في الدفعة الملغاة، لكن نتائجها لم تعد تحدّث عدادات الدفعة أو تؤدي إلى تشغيل `then` أو `catch` أو `finally`. احذف المهام بنفسك إذا كان يجب ألا تُنفّذ.

## العثور على الدفعات

ابحث عن دفعة باستخدام معرّفها:

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

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

## تنظيف الدفعات القديمة

أزِل الدفعات المنتهية التي مضى عليها عدد محدد من الأيام:

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

لا تُحذف إلا الدفعات التي تحتوي على طابع زمني غير فارغ لـ`finished_at`. ولا تُنظّف الدفعات النشطة مطلقًا.
