
# اعتماديات سيرورات العمل

استخدم انتظار اعتماديات سيرورات العمل عندما ينبغي ألا تتابع سيرورة عمل رئيسية إلا بعد اكتمال سيرورات عمل أخرى. يتيح ذلك التنسيق بين سيرورات العمل دون حشر كل شيء في تعريف واحد ضخم.

تتناسب هذه الانتظارات على نحو خاص مع [عمليات التسليم غير المتزامنة](https://queuety.inline0.dev/ar/docs/workflows/async-handoffs)، حيث تبدأ إحدى سيرورات العمل أولًا سيرورات عمل فرعية مستقلة ثم تنتظرها لاحقًا.

للاطلاع على أمثلة أشمل للمخطط والمنفذ، راجع [تنسيق الوكلاء](https://queuety.inline0.dev/ar/docs/workflows/agent-orchestration).

توفر Queuety ثلاث طرق للبناء:

- `wait_for_workflow()` لسيرورة عمل واحدة
- `wait_for_workflows()` لعدة سيرورات عمل بدلالات `all` أو `any` أو `quorum`
- `wait_for_workflow_group()` عندما تأتي معرّفات سيرورات العمل من مجموعة بدأ تشغيلها مسبقًا

## انتظار سيرورة عمل واحدة

```php
$research_id = Queuety::workflow( 'research_run' )
    ->then( PlanResearchStep::class )
    ->for_each( 'tasks', ExecuteResearchTask::class, 'results' )
    ->dispatch( [ 'brief_id' => 42 ] );

$editorial_id = Queuety::workflow( 'editorial_run' )
    ->wait_for_workflow( $research_id, 'research' )
    ->then( DraftBriefStep::class )
    ->dispatch();
```

عند اكتمال `research_run`، تُستأنف `editorial_run`. عند تعيين `result_key`، تُخزّن حالة التبعية المكتملة تحت ذلك المفتاح:

```php
$state['research']; // public state from the completed research workflow
```

إذا لم تُعيّن `result_key`، تُدمج الحالة العامة لسيرورة العمل التابعة في الحالة العليا لسيرورة العمل المنتظرة.

## انتظار عدة سيرورات عمل

```php
use Queuety\Enums\WaitMode;

Queuety::workflow( 'synthesis_run' )
    ->wait_for_workflows(
        [ $research_id, $editorial_id, $legal_id ],
        WaitMode::All,
        'dependencies'
    )
    ->then( PublishPacketStep::class )
    ->dispatch();
```

- لا تُستأنف `WaitMode::All` إلا بعد اكتمال كل سيرورات العمل المدرجة.
- تُستأنف `WaitMode::Any` عند اكتمال أول سيرورة عمل مدرجة.
- تُستأنف `WaitMode::Quorum` بعد اكتمال العدد المطلوب بنجاح من سيرورات العمل.

```php
Queuety::workflow( 'synthesis_run' )
    ->wait_for_workflows(
        [ $research_id, $editorial_id, $legal_id ],
        WaitMode::Quorum,
        'dependencies',
        quorum: 2,
    )
    ->then( PublishPacketStep::class )
    ->dispatch();
```

عند استخدام `result_key`، تخزن عمليات انتظار عدة سيرورات عمل حالة التبعيات المكتملة، ويكون مفتاحها معرّف سيرورة العمل:

```php
[
    '42' => [ 'summary' => '...' ],
    '43' => [ 'summary' => '...' ],
]
```

إذا لم تُعيّن `result_key`، تُدمج حالة التبعيات المكتملة في الحالة العليا لسيرورة العمل المنتظرة وفق ترتيب التبعيات.

## تحديد معرّفات التبعيات من حالة سيرورة العمل

يمكنك تأجيل تحديد قائمة التبعيات إلى وقت التشغيل عبر قراءة معرّفات سيرورات العمل من الحالة العامة:

```php
Queuety::workflow( 'agent_follow_up' )
    ->wait_for_workflow( 'parent_workflow_id', 'parent' )
    ->then( FinalizeAgentRunStep::class )
    ->dispatch( [ 'parent_workflow_id' => $workflow_id ] );
```

لعدة تبعيات:

```php
Queuety::workflow( 'aggregator' )
    ->wait_for_workflows( 'dependency_ids', WaitMode::Any, 'winner' )
    ->dispatch( [ 'dependency_ids' => [ 12, 18, 22 ] ] );
```

## انتظار مجموعة سيرورات عمل بدأ تشغيلها

إذا خزّنت خطوة سابقة من نوع `start_workflows()` أو `start_agents()` مفتاح مجموعة دائمًا، يمكنك الانتظار مباشرة على تلك المجموعة بدلًا من تمرير معرّفات سيرورات العمل يدويًا عبر الحالة العامة.

```php
Queuety::workflow( 'brief_research' )
    ->then( PlanTopicsStep::class )
    ->start_agents( 'agent_tasks', $agent_run, group_key: 'researchers' )
    ->wait_for_agent_group( 'researchers', WaitMode::Quorum, 2, 'agent_results' )
    ->then( SynthesizeBriefStep::class )
    ->dispatch();
```

## ما يحدث أثناء الانتظار

عندما تصل سيرورة عمل إلى إحدى هذه الخطوات، تنتقل إلى الحالة `waiting_for_workflows`. لا يبقى أي عامل مرتبطًا بها أثناء انتظارها.

```php
$state = Queuety::workflow_status( $workflow_id );
echo $state->status->value; // 'waiting_for_workflows'
echo $state->wait_type;     // 'workflow'
print_r( $state->waiting_for ); // ['42', '43']
```

إذا اكتملت تبعية بالفعل قبل بلوغ خطوة الانتظار، تتابع سيرورة العمل فورًا.

## دلالات الإخفاق

تركز عمليات انتظار اعتماديات سيرورات العمل على النجاح:

- تُخفق `wait_for_workflow()` و`WaitMode::All` إذا أخفقت أي تبعية مطلوبة أو أُلغيت.
- لا تُخفق `WaitMode::Any` إلا بعد وصول كل التبعيات إلى حالة نهائية من دون نجاح أي منها.
- تُخفق `WaitMode::Quorum` عندما لا يعود بإمكان سيرورات العمل النشطة المتبقية تحقيق النصاب المطلوب.

وهذا يجعل انتظار سيرورات العمل مفيدًا لأنظمة المخطط والمنفذ، حيث يمكن لسيرورة عمل بدء تنفيذ كل مهمة، ويمكن لأخرى انتظار نتائج `all` أو أول فرع ناجح يكتمل.
