
# الجدولة

Queuety يدعم الوظائف المتكررة مدمجًا. فبدلًا من الاعتماد على `wp_cron`، تُخزَّن الجداول في قاعدة البيانات وتُقيَّم بواسطة عملية `wp queuety work` طويلة التشغيل (أو العملية الأم لمجموعة العمال) مرة كل دقيقة تقريبًا. لا تقيّم `wp queuety work --once` و`wp queuety flush` وبديل WP-Cron المدمج في الإضافة الجداول ([#14](https://github.com/inline0/queuety/issues/14))؛ ومن دون عامل طويل التشغيل، شغّل `wp queuety schedule run` بنفسك.

## الجدولة بالفواصل الزمنية

استخدم `every()` للجداول البسيطة القائمة على الفواصل الزمنية. يمكن أن يكون التعبير أي سلسلة متوافقة مع PHP الخاص بـ`DateTimeImmutable::modify()`:

```php
use Queuety\Queuety;

Queuety::schedule( 'cleanup_handler' )
    ->every( '1 hour' )
    ->on_queue( 'maintenance' );

Queuety::schedule( 'sync_inventory' )
    ->every( '30 minutes' )
    ->on_queue( 'sync' );

Queuety::schedule( 'daily_report', [ 'type' => 'summary' ] )
    ->every( '1 day' );
```

## جدولة Cron

استخدم `cron()` لتعبيرات cron القياسية ذات الحقول الخمسة:

```php
// Every day at 3am
Queuety::schedule( 'nightly_cleanup' )
    ->cron( '0 3 * * *' );

// Every Monday at 9am
Queuety::schedule( 'weekly_digest' )
    ->cron( '0 9 * * 1' )
    ->on_queue( 'emails' );

// Every 15 minutes
Queuety::schedule( 'health_check' )
    ->cron( '*/15 * * * *' );
```

## خيارات الجدولة

يدعم المُنشئ `PendingSchedule` هذه الأساليب:

| الأسلوب | الوصف |
|---|---|
| `every( string $interval )` | تعيين تعبير الفاصل الزمني |
| `cron( string $expression )` | تعيين تعبير cron |
| `on_queue( string $queue )` | تعيين قائمة الانتظار المستهدفة (الافتراضية: `'default'`) |
| `overlap( OverlapPolicy $policy )` | تعيين سياسة التداخل (الافتراضية: `Allow`) |

يجب استدعاء `every()` أو `cron()` قبل إرسال الجدول. إذا لم يُعيَّن أي منهما، فسيُطرح `RuntimeException`.

## سياسات التداخل

عندما تظل وظيفة مجدولة قيد التشغيل (معلّقة أو قيد المعالجة) عند حلول الموعد التالي، تحدد سياسة التداخل ما سيحدث. عيّنها باستخدام الأسلوب `overlap()`:

```php
use Queuety\Queuety;
use Queuety\Enums\OverlapPolicy;

Queuety::schedule( 'sync_inventory' )
    ->every( '5 minutes' )
    ->overlap( OverlapPolicy::Skip )
    ->on_queue( 'sync' );
```

يتضمن التعداد `OverlapPolicy` ثلاث حالات:

| السياسة | القيمة | السلوك |
|---|---|---|
| `OverlapPolicy::Allow` | `allow` | أرسل دائمًا وظيفة جديدة، حتى إذا كان التشغيل السابق لا يزال نشطًا. هذا هو الإعداد الافتراضي. |
| `OverlapPolicy::Skip` | `skip` | تخطَّ الموعد الحالي إذا كانت للمعالج وظائف معلّقة أو قيد المعالجة. يُحدَّث `next_run` بشكل طبيعي ليظل الجدول على نسقه الزمني. |
| `OverlapPolicy::Buffer` | `buffer` | كما في Skip، لا يُرسل الموعد ويتقدم `next_run` إلى التكرار المنتظم التالي. بخلاف Skip، لا يُحدَّث `last_run`. |

### السماح (افتراضي)

يمكن تشغيل مثيلات متعددة من المعالج نفسه بالتزامن. استخدم هذا للمعالجات التي يمكن تكرارها بأمان، حيث لا يسبب التداخل مشكلة.

```php
Queuety::schedule( 'send_heartbeat_ping' )
    ->every( '1 minute' )
    ->overlap( OverlapPolicy::Allow );
```

### التخطي

يُتخطى الموعد بصمت إذا كان المعالج لا يزال قيد التشغيل. استخدم هذا للمعالجات التي يكون تشغيل مثيل ثانٍ منها مهدِرًا للموارد أو قد يسبب تعارضات.

```php
Queuety::schedule( 'rebuild_search_index' )
    ->every( '10 minutes' )
    ->overlap( OverlapPolicy::Skip );
```

### التخزين المؤقت

يعمل حاليًا مثل Skip: إذا كان للمعالج وظيفة معلّقة أو قيد المعالجة، فلا يُرسل الموعد ويتقدم `next_run` إلى التكرار المنتظم التالي. والفرق الوحيد أن Buffer يُبقي `last_run` دون تغيير، بينما يسجل Skip الموعد المتخطى باعتباره آخر تشغيل.

```php
Queuety::schedule( 'sync_inventory' )
    ->every( '5 minutes' )
    ->overlap( OverlapPolicy::Buffer );
```

## طريقة العمل

عند إنشاء جدول، يخزّنه Queuety في جدول `queuety_schedules` مع التعبير والمعالج والحمولة ووقت التشغيل التالي المحسوب.

في كل نبضة للمُجدول (مرة كل دقيقة تقريبًا في عامل طويل التشغيل، أو عند تشغيل `wp queuety schedule run`)، يتحقق المُجدول من الجداول التي انقضى `next_run` المحدد لها. ولكل جدول حان موعده، يرسل وظيفة جديدة ويحدّث `next_run` إلى التكرار التالي.

## إدارة الجداول عبر CLI

```bash
# List all schedules
wp queuety schedule list

# Add a recurring schedule
wp queuety schedule add cleanup_handler --every="1 hour"
wp queuety schedule add nightly_report --cron="0 3 * * *" --queue=reports

# Remove a schedule
wp queuety schedule remove cleanup_handler

# Manually trigger the scheduler
wp queuety schedule run
```

## إدارة الجداول عبر PHP

```php
// Get the scheduler instance
$scheduler = Queuety::scheduler();

// List all schedules
$schedules = $scheduler->list();

// Remove a schedule by handler name
$scheduler->remove( 'cleanup_handler' );

// Manually trigger a tick
$count = $scheduler->tick();
```

## الحمولة

يمكن أن تتضمن الجداول حمولة ثابتة تُمرر إلى كل وظيفة مرسلة:

```php
Queuety::schedule( 'generate_report', [ 'type' => 'daily', 'format' => 'pdf' ] )
    ->every( '1 day' )
    ->on_queue( 'reports' );
```

في كل مرة يحين فيها موعد الجدول، تُرسل وظيفة جديدة بهذه الحمولة.
