
# البدء

## التثبيت

### المتطلبات

- PHP 8.2 أو أحدث وWordPress 6.4 أو أحدث
- MySQL 8.0+ أو MariaDB 10.6+. يطالب العمال بالمهام والجداول المستحقة باستخدام `SELECT ... FOR UPDATE SKIP LOCKED`، وترفض الخوادم الأقدم ذلك بخطأ في الصياغة.
- `mysqli` أو `pdo_mysql` (انظر أدناه)
- WP-CLI على الخادم إذا كنت تشغّل عمالًا مخصصين باستخدام `wp queuety work`
- إضافتا `pcntl` و`posix` PHP إذا كنت تشغّل مجموعات عمال باستخدام `--workers` أو `--min-workers`/`--max-workers`

يتطلب Queuety إما `mysqli` أو `pdo_mysql` في بيئة تشغيل PHP التي تحمّل WordPress وWP-CLI. يختار المشغل تلقائيًا، مع تفضيل `mysqli` لبيئات تشغيل WordPress وإبقاء `pdo_mysql` متاحًا للاستخدام المستقل أو المباشر.

إذا أردت بيئة تشغيل مدعومة بقاعدة البيانات من دون طبقة إضافة WordPress، راجع [الاستخدام المستقل](https://queuety.inline0.dev/ar/docs/features/standalone-use). يستخدم هذا المسار الاتصال نفسه وجداول بيئة التشغيل، لكنه لا يتضمن جسور خطافات WordPress أو تسجيل WP-CLI.

### من ملف الإصدار المضغوط

يتضمن كل إصدار من [GitHub](https://github.com/inline0/queuety/releases) ملف `queuety.zip`: الإضافة مع تثبيت تبعيات Composer مسبقًا. ثبّت أحدث إصدار باستخدام WP-CLI:

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

أو نزّل الملف المضغوط وارفعه من الإضافات > أضف إضافة جديدة > رفع إضافة. هذا أبسط مسار لموقع WordPress عادي.

### عبر Composer لمواقع WordPress التي تدير تبعياتها باستخدام Composer

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

ثم فعّل الإضافة:

```bash
wp plugin activate queuety
```

نوع الحزمة هو `wordpress-plugin`. لا يضع Composer الحزمة في مجلد الإضافات إلا عندما يتطلب المشروع `composer/installers` ويربط ذلك النوع بمسار تثبيت، كما يفعل Bedrock، ويجب أن يحمّل المشروع ملف `vendor/autoload.php` الخاص به (وهذا ما يفعله Bedrock أيضًا). من دون `composer/installers`، يثبتها Composer في `vendor/queuety/queuety`، حيث لا يعثر عليها WordPress، لذا استخدم ملف الإصدار المضغوط في تثبيت WordPress عادي.

### من المصدر أثناء التطوير

ضع المستودع في `wp-content/plugins/queuety`، ثم ثبّت تبعيات PHP:

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

عند التفعيل، ينشئ Queuety جداول قاعدة البيانات الخاصة به (`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`) كي يتمكن العمال من المطالبة بالمهام مباشرةً من MySQL.

افتراضيًا، يجدول المكون الإضافي أيضًا عاملًا لمرة واحدة عبر WordPress cron كل دقيقة لطابور `default`. يوفّر هذا خيارًا أساسيًا بلا صدفة للمهام ومسارات العمل التي تعمل على `default`، ما دامت WordPress cron تعمل. تعالج كل عملية تشغيل مهمة واحدة كحد أقصى، ولا تشغّل الجداول المتكررة أو تسترد المهام القديمة أو تتحقق من المواعيد النهائية لسير العمل؛ فهذه المهام لا تعمل إلا ضمن عملية `wp queuety work` طويلة التشغيل ([#14](https://github.com/inline0/queuety/issues/14)). للطوابير المخصصة أو الجداول المتكررة أو زمن استجابة أقل أو أعباء العمل الأكبر، انتقل إلى عمليات `wp queuety work` مخصصة.

## الإعداد

كل الثوابت اختيارية. عرّفها في `wp-config.php` قبل تحميل الإضافة، أو قبل بدء Queuety في تثبيت مضمّن بأسلوب القوالب:

| الثابت | الافتراضي | الوصف |
|---|---|---|
| `QUEUETY_RETENTION_DAYS` | `7` | العمر الافتراضي بالأيام لـ `wp queuety purge` و`Queuety::purge()`. لا تُحذف أي بيانات تلقائيًا |
| `QUEUETY_LOG_RETENTION_DAYS` | `0` | يُقرأ بواسطة `Config::log_retention_days()` لكنه غير مستخدم بعد؛ تُحتفظ بالسجلات حتى تستدعي `Queuety::purge_logs()` ([#15](https://github.com/inline0/queuety/issues/15)) |
| `QUEUETY_MAX_EXECUTION_TIME` | `300` | الحد الأقصى لعدد الثواني لكل مهمة قبل انتهاء المهلة (غير مفروض بعد، راجع [Jobs](https://queuety.inline0.dev/ar/docs/jobs#timeout)) |
| `QUEUETY_WORKER_SLEEP` | `1` | عدد الثواني للانتظار عندما يكون صف الانتظار فارغًا |
| `QUEUETY_WORKER_MAX_JOBS` | `1000` | الحد الأقصى للمهام قبل إعادة تشغيل العامل |
| `QUEUETY_WORKER_MAX_MEMORY` | `128` | الحد الأقصى للذاكرة بالميغابايت قبل إعادة تشغيل العامل |
| `QUEUETY_RETRY_BACKOFF` | `exponential` | استراتيجية التراجع: `exponential` أو `linear` أو `fixed` |
| `QUEUETY_STALE_TIMEOUT` | `600` | عدد الثواني قبل استعادة المهام العالقة |
| `QUEUETY_CACHE_TTL` | `5` | القيمة الافتراضية لمدة صلاحية ذاكرة التخزين المؤقت بالثواني |
| `QUEUETY_DEBUG` | `false` | تفعيل التسجيل التفصيلي للعامل |
| `QUEUETY_CLI_COMMAND` | `queuety` | اسم الأمر الأساسي لـ WP-CLI |
| `QUEUETY_TABLE_PREFIX` | `queuety_` | الاسم الأساسي المشترك لكل جداول Queuety بعد بادئة قاعدة البيانات WordPress |
| `QUEUETY_TABLE_JOBS` | `queuety_jobs` | اسم جدول المهام |
| `QUEUETY_TABLE_WORKFLOWS` | `queuety_workflows` | اسم جدول سير العمل |
| `QUEUETY_TABLE_LOGS` | `queuety_logs` | اسم جدول السجلات |
| `QUEUETY_TABLE_SCHEDULES` | `queuety_schedules` | اسم جدول الجداول الزمنية |
| `QUEUETY_TABLE_SIGNALS` | `queuety_signals` | اسم جدول الإشارات |
| `QUEUETY_TABLE_WORKFLOW_DEPENDENCIES` | `queuety_workflow_dependencies` | اسم جدول انتظار تبعيات سير العمل |
| `QUEUETY_TABLE_WORKFLOW_DISPATCH_KEYS` | `queuety_workflow_dispatch_keys` | اسم جدول منع تكرار سير العمل الدائم |
| `QUEUETY_TABLE_CHUNKS` | `queuety_chunks` | اسم جدول أجزاء البث |
| `QUEUETY_TABLE_QUEUE_STATES` | `queuety_queue_states` | اسم جدول حالات صفوف الانتظار |
| `QUEUETY_TABLE_WEBHOOKS` | `queuety_webhooks` | اسم جدول خطافات الويب |
| `QUEUETY_TABLE_LOCKS` | `queuety_locks` | اسم جدول الأقفال |
| `QUEUETY_TABLE_BATCHES` | `queuety_batches` | اسم جدول الدفعات |
| `QUEUETY_TABLE_WORKFLOW_EVENTS` | `queuety_workflow_events` | اسم جدول سجل أحداث سير العمل |
| `QUEUETY_TABLE_ARTIFACTS` | `queuety_artifacts` | اسم جدول عناصر سير العمل |
| `QUEUETY_TABLE_STATE_MACHINES` | `queuety_state_machines` | اسم جدول آلات الحالات |
| `QUEUETY_TABLE_STATE_MACHINE_EVENTS` | `queuety_state_machine_events` | اسم جدول سجل أحداث آلة الحالات |
| `QUEUETY_DB_DRIVER` | `auto` | برنامج تشغيل MySQL: `auto` أو `mysqli` أو `pdo`. يفضّل `auto` استخدام `mysqli` عند تحميل WordPress، وإلا فـ `pdo_mysql`، ثم `mysqli` |

تُسرد ثوابت قبول الموارد والمجمع التكيفي (`QUEUETY_RESOURCE_*` و`QUEUETY_WORKER_POOL_*`) في صفحة [Workers](https://queuety.inline0.dev/ar/docs/features/workers).

يغيّر `QUEUETY_TABLE_PREFIX` الجزء Queuety فقط من أسماء الجداول. تظل بادئة قاعدة البيانات WordPress مضافة إلى الناتج، لذا ينتج عن `$wpdb->prefix = 'wp_'` و`QUEUETY_TABLE_PREFIX = 'themequeue_'` جداول مثل `wp_themequeue_jobs`. وتظل للثوابت الصريحة `QUEUETY_TABLE_*` الأولوية في الجداول الفردية.

يمكن للاتصالات المستقلة أيضًا تعيين بادئة الجدول Queuety لكل اتصال:

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

يحافظ ذلك على بادئة قاعدة البيانات WordPress كما هي، ولا يغيّر سوى مقطع الجدول Queuety.

## مهمتك الأولى

أنشئ فئة معالج تنفّذ الواجهة `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,
        ];
    }
}
```

سجّلها وأرسل المهمة:

```php
use Queuety\Queuety;

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

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

أو استخدم فئة المهمة الحديثة القابلة للإرسال:

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

## أول سير عمل لك

عرّف معالجات الخطوات التي تنفّذ الواجهة `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 [];
    }
}
```

أرسل سير العمل:

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

## بدء عامل

```bash
wp queuety work
```

يستطلع العامل المهام المعلّقة، وينفذها، ويدفع سير العمل إلى الأمام، وينتظر عندما يكون صف الانتظار فارغًا. اضغط `Ctrl+C` لإيقافه؛ ينهي ذلك العملية فورًا، حتى في منتصف تنفيذ مهمة (راجع [Workers](https://queuety.inline0.dev/ar/docs/features/workers#worker-lifecycle)).

يرسل `SendEmailHandler` أعلاه مهامه إلى صف الانتظار `emails` عبر `config()`، لذا لن يلتقطها عامل يعمل على `default`. سمِّ كل صف انتظار تستخدمه:

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

إذا لم تشغّل عاملًا مخصصًا، فسيظل Queuety يستخدم آلية الرجوع الافتراضية WordPress cron التي تعمل مرة كل دقيقة كما هو موضح أعلاه، وتقتصر على صف الانتظار `default` ومهمة واحدة في كل تشغيل. العامل المخصص هو الخيار الأعلى إنتاجية والأقل زمنًا للاستجابة.

لبيئة الإنتاج، شغّل عدة عمال:

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

عالج عدة صفوف انتظار مع ترتيب حسب الأولوية:

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

## الخطوات التالية

- [Jobs](https://queuety.inline0.dev/ar/docs/jobs) للاطلاع على الدليل الكامل لإرسال المهام ومعالجتها
- [Workflows](https://queuety.inline0.dev/ar/docs/workflows) للاطلاع على السلاسل والخطوات المتوازية والتفرع الشرطي وتشغيل سير العمل
- [Middleware](https://queuety.inline0.dev/ar/docs/features/middleware) للاطلاع على تحديد معدل الطلبات والخنق ومنطق مسار المعالجة المخصص
- [Batching](https://queuety.inline0.dev/ar/docs/features/batching) لإرسال مجموعات من المهام مع دوال رد الاتصال
- [Streaming Steps](https://queuety.inline0.dev/ar/docs/workflows/streaming) لحفظ بيانات البث جزءًا بعد جزء
- [Scheduling](https://queuety.inline0.dev/ar/docs/features/scheduling) للمهام المتكررة
- [Caching](https://queuety.inline0.dev/ar/docs/features/caching) لطبقة التخزين المؤقت القابلة للتبديل
- [Testing](https://queuety.inline0.dev/ar/docs/features/testing) لاستخدام QueueFake وعمليات التأكيد في الاختبارات
- [CLI Reference](https://queuety.inline0.dev/ar/docs/cli) للاطلاع على جميع الأوامر المتاحة
- [PHP API](https://queuety.inline0.dev/ar/docs/api) للوصول البرمجي
