التكرارات
مسارات العمل في Queuety سلاسل خطوات مرتبة. استخدم خطوة تحكم بالتكرار للعودة إلى خطوة سابقة مسماة بدلًا من كتابة منطق _next_step يدويًا.
اختر الصيغة المناسبة لسير العمل:
- استخدم
state_keyعامًا عندما يكون الشرط بسيطًا - استخدم
condition_classعندما يحتاج التكرار إلى منطق أكثر تعقيدًا - استخدم
max_iterationsعندما يحتاج التكرار نفسه إلى حد توقف صارم
تستهدف الطريقتان خطوة سابقة مسماة، لذا يظل التكرار قابلًا للتسلسل وإعادة التشغيل، ومحكومًا بوقت تشغيل سير العمل نفسه كسائر الخطوات.
يُقيّم شرط التكرار من حالة سير العمل العامة المحفوظة بعد اكتمال الخطوة السابقة، لذا تظل كل دورة مستدامة عبر عمليات إعادة تشغيل العامل.
repeat_until() باستخدام مفتاح حالة
Queuety::workflow( 'approval_revision_loop' )
->max_transitions( 12 )
->then( DraftBriefStep::class, 'draft' )
->wait_for_decision( result_key: 'review' )
->then( NormalizeReviewOutcomeStep::class, 'review_outcome' )
->repeat_until( 'draft', 'review_approved', true, 'repeat_draft_until_approved' )
->then( PublishBriefStep::class )
->dispatch( [ 'brief_id' => 42 ] );
يمكن لـ NormalizeReviewOutcomeStep اختزال حمولة القرار إلى مفتاح عام بسيط:
class NormalizeReviewOutcomeStep implements \Queuety\Step {
public function handle( array $state ): array {
return [
'review_approved' => 'approved' === ( $state['review']['outcome'] ?? null ),
];
}
public function config(): array {
return [];
}
}
إذا لم تصبح review_approved بعدُ true، تقفز خطوة التكرار عائدةً إلى draft. وعندما تصبح true، ينتقل سير العمل إلى PublishBriefStep.
تُخزن الإشارات ولا تُستهلك. في المرور الثاني عبر wait_for_decision()، تظل الإشارة السابقة rejected مطابقة، وينتهي الانتظار فورًا، لذا ستستمر الحلقة في الدوران حتى يوقفها max_transitions(). خصص مفتاحًا لكل جولة: اجعل DraftBriefStep يعيد review_round متزايدًا، ومرر correlation_key: 'review_round' إلى wait_for_decision()، واجعل المراجع يرسل review_round نفسه في حمولة الإشارة. عندئذٍ لا ينهي الانتظار إلا signal whose review_round يساوي قيمة الحالة الحالية.
repeat_until() باستخدام فئة شرط
use App\Workflows\ReviewApprovedCondition;
Queuety::workflow( 'approval_revision_loop' )
->then( DraftBriefStep::class, 'draft' )
->wait_for_decision( result_key: 'review' )
->repeat_until(
target_step: 'draft',
condition_class: ReviewApprovedCondition::class,
max_iterations: 5,
name: 'repeat_draft_until_approved',
)
->then( PublishBriefStep::class )
->dispatch( [ 'brief_id' => 42 ] );
namespace App\Workflows;
use Queuety\Contracts\RepeatCondition;
final class ReviewApprovedCondition implements RepeatCondition {
public function matches( array $state ): bool {
return 'approved' === ( $state['review']['outcome'] ?? null );
}
}
تتلقى فئات الشروط حالة سير العمل العامة، لذا يظل الشرط قابلًا للتسلسل والفحص دون الاعتماد على الإغلاقات.
repeat_while()
Queuety::workflow( 'poll_remote_status' )
->max_transitions( 20 )
->then( PollRemoteStatusStep::class, 'poll' )
->delay( seconds: 30 )
->repeat_while( 'poll', 'should_poll_again', true, 'repeat_poll' )
->then( FinalizeImportStep::class )
->dispatch( [ 'import_id' => 99 ] );
يفيد هذا النمط عندما تكتب إحدى الخطوات قيمة منطقية بسيطة مثل should_poll_again أو has_more_pages أو needs_revision.
لماذا تكون التكرارات منفصلة عن _next_step
لا يزال بإمكانك إنشاء تفرع يدويًا بإرجاع _next_step من خطوة عادية. صُممت أدوات التكرار المساعدة للحالات الأضيق التالية:
- تكون الخطوة المستهدفة خطوة سابقة
- يأتي الشرط من حالة سير العمل العامة
- تريد أن يظل منطق التكرار ظاهرًا في تعريف سير العمل نفسه
وهذا يجعل فحص التكرارات في عمليات التصدير وسجلات الأحداث والوثائق أسهل من إخفاء حافة الرجوع داخل شيفرة خطوة عشوائية.
وضع قيود على التكرارات
استخدم max_iterations عندما يحتاج تكرار محدد إلى حد إيقاف محلي:
Queuety::workflow( 'poll_remote_status' )
->then( PollRemoteStatusStep::class, 'poll' )
->repeat_while( 'poll', 'should_poll_again', true, max_iterations: 8 )
->dispatch();
استخدم max_transitions() عندما يحتاج سير العمل بأكمله إلى مفتاح إيقاف طارئ أوسع نطاقًا:
Queuety::workflow( 'safe_revision_loop' )
->max_transitions( 10 )
->then( DraftBriefStep::class, 'draft' )
->wait_for_decision( result_key: 'review' )
->then( NormalizeReviewOutcomeStep::class )
->repeat_until( 'draft', 'review_approved', true )
->dispatch();
إذا تجاوز تكرار max_iterations، أو تجاوز سير العمل max_transitions()، فستُفشل Queuety التشغيل بدلًا من تركه يدور إلى الأبد.