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
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:
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
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 );
}
}
Betingelsesklasser modtager den offentlige workflowtilstand, så prædikatet forbliver serialiserbart og inspicerbart uden at være afhængigt af closures.
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 ] );
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:
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:
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.