Lewati ke konten

Pengulangan

Queuety alur kerja adalah rangkaian langkah yang berurutan. Gunakan langkah kontrol pengulangan untuk kembali ke langkah bernama sebelumnya alih-alih menulis sendiri logika _next_step.

Pilih bentuk yang sesuai dengan alur kerja:

  • state_key publik jika kondisinya sederhana
  • condition_class jika pengulangan memerlukan logika yang lebih kompleks
  • max_iterations jika pengulangan itu sendiri memerlukan batas penghentian tegas

Kedua metode menargetkan langkah bernama sebelumnya, sehingga pengulangan tetap dapat diserialisasi, diputar ulang, dan dijaga oleh runtime alur kerja yang sama seperti langkah lainnya.

Kondisi pengulangan dievaluasi dari status alur kerja publik yang tersimpan setelah langkah sebelumnya selesai, sehingga setiap iterasi tetap tahan lama meski worker dimulai ulang.

repeat_until() dengan kunci status

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 dapat menyederhanakan payload keputusan menjadi kunci publik:

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

Jika review_approved masih belum true, langkah pengulangan melompat kembali ke draft. Setelah nilainya menjadi true, alur kerja berlanjut ke PublishBriefStep.

Sinyal disimpan, bukan dikonsumsi. Pada putaran kedua melalui wait_for_decision(), sinyal rejected sebelumnya masih cocok dan penantian langsung selesai, sehingga loop akan berputar terus hingga max_transitions() menghentikannya. Beri setiap putaran kunci tersendiri: minta DraftBriefStep mengembalikan review_round yang bertambah, berikan correlation_key: 'review_round' ke wait_for_decision(), dan minta peninjau mengirim review_round yang sama dalam payload sinyal. Hanya sinyal dengan review_round yang sama dengan nilai status saat ini yang akan menyelesaikan penantian.

repeat_until() dengan kelas kondisi

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

Kelas kondisi menerima status alur kerja publik, sehingga predikat dapat diserialisasi dan diperiksa tanpa bergantung pada closure.

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

Pola ini berguna ketika langkah menulis boolean sederhana seperti should_poll_again, has_more_pages, atau needs_revision.

Mengapa pengulangan terpisah dari _next_step

Anda tetap dapat membuat percabangan secara manual dengan mengembalikan _next_step dari langkah biasa. Helper pengulangan tersedia untuk kasus yang lebih spesifik ketika:

  • targetnya adalah langkah sebelumnya
  • kondisinya berasal dari status alur kerja publik
  • Anda ingin logika pengulangan tetap terlihat dalam definisi alur kerja itu sendiri

Dengan begitu, pengulangan lebih mudah diperiksa dalam ekspor, log peristiwa, dan dokumentasi dibandingkan menyembunyikan alur balik di dalam kode langkah sembarang.

Membatasi pengulangan

Gunakan max_iterations saat satu pengulangan tertentu memerlukan batas penghentian tegas:

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

Gunakan max_transitions() saat seluruh alur kerja memerlukan sakelar pengaman yang lebih luas:

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

Jika pengulangan melampaui max_iterations, atau alur kerja melampaui max_transitions(), Queuety akan menggagalkan eksekusi alih-alih membiarkannya berputar selamanya.