Hoppa till innehåll

Upprepningar

Queuety arbetsflöden består av ordnade stegkedjor. Använd ett upprepningssteg för att återgå till ett tidigare namngivet steg i stället för att skriva _next_step-logik för hand.

Välj den form som passar arbetsflödet:

  • en offentlig state_key när villkoret är enkelt
  • en condition_class när upprepningen kräver mer avancerad logik
  • max_iterations när själva upprepningen behöver en tydlig gräns

Båda metoderna riktar sig mot ett tidigare namngivet steg, så upprepningen förblir serialiserbar, återspelningsbar och skyddad av samma arbetsflödeskörmiljö som alla andra steg.

Upprepningsvillkoret utvärderas från det beständiga offentliga arbetsflödestillståndet när det föregående steget har slutförts, så varje iteration förblir beständig även efter omstarter av arbetare.

repeat_until() med en tillståndsnyckel

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 platta till beslutsnyttolasten till en enkel offentlig nyckel:

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

Om review_approved fortfarande inte är true hoppar upprepningssteget tillbaka till draft. När det blir true fortsätter arbetsflödet till PublishBriefStep.

Signaler lagras, de förbrukas inte. Vid den andra genomgången av wait_for_decision() matchar den tidigare rejected-signalen fortfarande och väntan avslutas omedelbart, så loopen skulle snurra tills max_transitions() stoppar den. Ge varje omgång en egen nyckel: låt DraftBriefStep returnera ett inkrementerande review_round, skicka correlation_key: 'review_round' till wait_for_decision() och låt granskaren skicka samma review_round i signalens nyttolast. Då avslutas väntan bara när en signal vars review_round motsvarar det aktuella tillståndsvärdet tas emot.

repeat_until() med en villkorsklass

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

Villkorsklasser får det offentliga arbetsflödestillståndet, så predikatet förblir serialiserbart och granskningsbart utan att vara beroende av 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 ] );

Mönstret är användbart när ett steg skriver ett enkelt booleskt värde som should_poll_again, has_more_pages eller needs_revision.

Varför upprepningar är separata från _next_step

Du kan fortfarande skapa grenar manuellt genom att returnera _next_step från ett vanligt steg. Hjälpfunktionerna för upprepning finns för det mer avgränsade fallet när:

  • målet är ett tidigare steg
  • villkoret kommer från det offentliga arbetsflödestillståndet
  • du vill att upprepningslogiken ska vara synlig i själva arbetsflödesdefinitionen

Det gör upprepningar enklare att granska i exporter, händelseloggar och dokumentation än om återkopplingen göms i godtycklig stegspecifik kod.

Begränsa upprepningar

Använd max_iterations när en viss upprepning behöver en lokal gräns:

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

Använd max_transitions() när hela arbetsflödet behöver en bredare nödbrytare:

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

Om en upprepning överskrider max_iterations, eller arbetsflödet överskrider max_transitions(), avbryter Queuety körningen i stället för att låta den snurra för alltid.