Повторения
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 в полезния товар на сигнала. Тогава изчакването приключва само при сигнал, чиято 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 прекратява изпълнението, вместо да му позволява да се върти безкрайно.