Gå til indhold

Gentagelser

Queuety workflows består af ordnede trinsekvenser. Brug et gentagelseskontroltrin til at vende tilbage til et tidligere navngivet trin i stedet for selv at skrive _next_step-logik.

Vælg den form, der passer til workflowet:

  • en offentlig state_key, når betingelsen er enkel
  • en condition_class, når gentagelsen kræver mere omfattende logik
  • max_iterations, når gentagelsen skal have en fast grænse

Begge metoder retter sig mod et tidligere navngivet trin, så gentagelsen forbliver serialiserbar, afspilbar og beskyttet af samme workflowruntime som alle andre trin.

Gentagelsesbetingelsen evalueres ud fra den gemte offentlige workflowtilstand, når det foregående trin er fuldført, så hver gentagelse forbliver holdbar på tværs af genstarter af workerprocessen.

repeat_until() med en tilstandsnøgle

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 kan samle beslutningsnyttelasten i en enkel offentlig nøgle:

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 [];
    }
}

Hvis review_approved stadig ikke er true, springer gentagelsestrinnet tilbage til draft. Når det bliver true, fortsætter workflowet til PublishBriefStep.

Signaler gemmes, de forbruges ikke. Ved anden gennemgang af wait_for_decision() matcher det tidligere rejected-signal stadig, og ventetiden afsluttes med det samme, så løkken ville køre i ring, indtil max_transitions() stopper den. Giv hver runde sin egen nøgle: Lad DraftBriefStep returnere en stigende review_round, send correlation_key: 'review_round' til wait_for_decision(), og lad bedømmeren sende samme review_round i signalnyttelasten. Så afslutter kun et signal, hvor review_round svarer til den aktuelle tilstandsværdi, ventetiden.

repeat_until() med en betingelsesklasse

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 );
    }
}

Betingelsesklasser modtager den offentlige workflowtilstand, så prædikatet forbliver serialiserbart og inspicerbart uden at være afhængigt af closures.

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

Dette mønster er nyttigt, når et trin skriver en enkel boolesk værdi som should_poll_again, has_more_pages eller needs_revision.

Hvorfor gentagelser er adskilt fra _next_step

Du kan stadig forgrene manuelt ved at returnere _next_step fra et normalt trin. Gentagelsesfunktionerne findes til det mere afgrænsede tilfælde, hvor:

  • målet er et tidligere trin
  • betingelsen kommer fra den offentlige workflowtilstand
  • du ønsker, at gentagelseslogikken skal være synlig i selve workflowdefinitionen

Det gør gentagelser nemmere at inspicere i eksporter, hændelseslogfiler og dokumentation end at skjule tilbagekanten i vilkårlig trinkode.

Begrænsning af gentagelser

Brug max_iterations, når en bestemt gentagelse skal have en lokal fast grænse:

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

Brug max_transitions(), når hele workflowet skal have en bredere livlineafbryder:

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

Hvis en gentagelse overskrider max_iterations, eller workflowet overskrider max_transitions(), fejler Queuety kørslen i stedet for at lade den køre i ring for evigt.