Preskočiť na obsah

Opakovania

Queuety sú usporiadané reťazce krokov. Pomocou riadiaceho kroku opakovania sa môžete vrátiť k predchádzajúcemu pomenovanému kroku namiesto ručného písania logiky _next_step.

Vyberte formu, ktorá zodpovedá pracovnému postupu:

  • verejné state_key, ak je podmienka jednoduchá
  • condition_class, ak opakovanie vyžaduje zložitejšiu logiku
  • max_iterations, ak opakovanie potrebuje pevný limit

Obe metódy smerujú na predchádzajúci pomenovaný krok, takže opakovanie zostáva serializovateľné, prehrateľné a podlieha rovnakému modulu runtime pracovného postupu ako všetky ostatné kroky.

Podmienka opakovania sa vyhodnotí z uloženého verejného stavu pracovného postupu po dokončení predchádzajúceho kroku, takže každé opakovanie zostáva trvalé aj po reštarte pracovníka.

repeat_until() s kľúčom stavu

PHP
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 môže zjednodušiť údaje o rozhodnutí na jednoduchý verejný kľúč:

PHP
class NormalizeReviewOutcomeStep implements \Queuety\Step {
    public function handle( array $state ): array {
        return [
            'review_approved' => 'approved' === ( $state['review']['outcome'] ?? null ),
        ];
    }

    public function config(): array {
        return [];
    }
}

Ak review_approved stále nie je true, krok opakovania sa vráti na draft. Keď sa zmení na true, pracovný postup pokračuje krokom PublishBriefStep.

Signály sa ukladajú, nespotrebúvajú sa. Pri druhom prechode cez wait_for_decision() sa stále zhoduje predchádzajúci signál rejected a čakanie sa okamžite skončí, takže slučka by sa opakovala, kým ju nezastaví max_transitions(). Každému kolu priraďte vlastný kľúč: nech DraftBriefStep vráti rastúce review_round, odovzdajte correlation_key: 'review_round' funkcii wait_for_decision() a nech kontrolór odošle rovnaké review_round v údajoch signálu. Čakanie sa potom ukončí iba vtedy, keď sa review_round signálu rovná aktuálnej hodnote stavu.

repeat_until() s triedou podmienky

PHP
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 ] );
PHP
namespace App\Workflows;

use Queuety\Contracts\RepeatCondition;

final class ReviewApprovedCondition implements RepeatCondition {
    public function matches( array $state ): bool {
        return 'approved' === ( $state['review']['outcome'] ?? null );
    }
}

Triedy podmienok dostávajú verejný stav pracovného postupu, takže predikát zostáva serializovateľný a kontrolovateľný bez závislosti od uzáverov.

repeat_while()

PHP
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 ] );

Tento vzor je užitočný, keď krok zapíše jednoduchú booleovskú hodnotu, napríklad should_poll_again, has_more_pages alebo needs_revision.

Prečo sú opakovania oddelené od _next_step

Vetviť môžete aj ručne tak, že z bežného kroku vrátite _next_step. Pomocné funkcie na opakovanie slúžia na užší prípad, keď:

  • cieľom je predchádzajúci krok
  • podmienka vychádza z verejného stavu pracovného postupu
  • chcete, aby logika opakovania zostala viditeľná priamo v definícii pracovného postupu

Vďaka tomu sa opakovania ľahšie kontrolujú v exportoch, protokoloch udalostí a dokumentácii než pri skrytí spätného prepojenia v ľubovoľnom kóde kroku.

Ochrana pred nekonečným opakovaním

Ak jedno konkrétne opakovanie potrebuje miestny pevný limit, použite max_iterations:

PHP
Queuety::workflow( 'poll_remote_status' )
    ->then( PollRemoteStatusStep::class, 'poll' )
    ->repeat_while( 'poll', 'should_poll_again', true, max_iterations: 8 )
    ->dispatch();

Ak celý pracovný postup potrebuje širšiu poistku, použite max_transitions():

PHP
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();

Ak opakovanie prekročí max_iterations alebo pracovný postup prekročí max_transitions(), Queuety zlyhaním ukončí beh, aby sa nikdy neopakoval donekonečna.