Μετάβαση στο περιεχόμενο

Δυναμικό For-Each

Χρησιμοποιήστε το ->for_each() όταν ο αριθμός των διακλαδώσεων της ροής εργασίας δεν είναι γνωστός κατά τη δημιουργία της. Το Queuety διαβάζει έναν πίνακα από την κατάσταση της ροής εργασίας, αποστέλλει μία εργασία διακλάδωσης ανά στοιχείο και προχωρά μόνο όταν ικανοποιηθεί η διαμορφωμένη συνθήκη ολοκλήρωσης.

Η μέθοδος ->for_each()

PHP
use Queuety\Contracts\ForEachHandler;
use Queuety\Contracts\ForEachReducer;
use Queuety\Enums\ForEachMode;
use Queuety\Queuety;

Queuety::workflow( 'index_site' )
    ->then( PlanPagesStep::class )
    ->for_each(
        items_key: 'pages',
        handler_class: IndexPageStep::class,
        result_key: 'page_results',
        mode: ForEachMode::Quorum,
        quorum: 2,
        reducer_class: IndexSummaryReducer::class,
        name: 'index_pages',
    )
    ->then( PublishIndexStep::class )
    ->dispatch( [ 'site_id' => 42 ] );

Το βήμα σχεδιασμού γράφει το pages στην κατάσταση της ροής εργασίας. Το βήμα for-each διαβάζει αυτόν τον πίνακα και αποστέλλει μία εργασία διακλάδωσης ανά στοιχείο.

Χειριστές διακλάδωσης

Οι χειριστές διακλάδωσης for-each υλοποιούν το Contracts\ForEachHandler:

PHP
use Queuety\Contracts\ForEachHandler;

final class IndexPageStep implements ForEachHandler {
    public function handle_item( array $state, mixed $item, int $index ): array {
        $page = is_array( $item ) ? $item : [ 'url' => (string) $item ];

        return [
            'url' => $page['url'],
            'title' => fetch_title( $page['url'] ),
            'index' => $index,
        ];
    }

    public function config(): array {
        return [
            'max_attempts' => 3,
            'backoff' => 'exponential',
        ];
    }
}

Στο config(), το backoff δέχεται ένα όνομα στρατηγικής: exponential, linear ή fixed. Μια λίστα καθυστερήσεων ανά προσπάθεια απορρίπτεται αυτήν τη στιγμή και μετατρέπεται σε άμεσες επαναλήψεις (#16)· ορίστε τις καθυστερήσεις ανά προσπάθεια στο backoff του ορισμού του βήματος.

Το $state περιέχει ολόκληρη την κατάσταση της ροής εργασίας, το $item είναι το μεμονωμένο στοιχείο for-each και το $index είναι η θέση του, με αρίθμηση από το μηδέν.

Λειτουργίες ολοκλήρωσης

ForEachMode::All

Το βήμα ολοκληρώνεται μόνο αφού επιτύχουν όλες οι διακλαδώσεις. Οποιαδήποτε οριστική αποτυχία διακλάδωσης προκαλεί αποτυχία του βήματος for-each.

ForEachMode::FirstSuccess

Το βήμα ολοκληρώνεται μόλις επιτύχει η πρώτη διακλάδωση. Οι υπόλοιπες ενεργές διακλαδώσεις θάβονται ως αντικατασταθείσες.

ForEachMode::Quorum

Το βήμα ολοκληρώνεται όταν επιτύχουν τουλάχιστον quorum διακλαδώσεις. Αν οι υπόλοιπες διακλαδώσεις δεν μπορούν πλέον να ικανοποιήσουν την απαρτία, η ροή εργασίας αποτυγχάνει.

Συναρτήσεις μείωσης

Από προεπιλογή, το Queuety αποθηκεύει μια δομημένη συνάθροιση στο result_key:

  • mode
  • quorum
  • total
  • succeeded
  • failed
  • settled
  • winner
  • results
  • failures

Αν θέλετε μια προσαρμοσμένη σύνοψη, περάστε μια κλάση reducer που υλοποιεί το Contracts\ForEachReducer. Η συνάθροιση εξακολουθεί να αποθηκεύεται στο result_key και τα κλειδιά που επιστρέφει ο reducer συγχωνεύονται στην κατάσταση της ροής εργασίας δίπλα της:

PHP
use Queuety\Contracts\ForEachReducer;

final class IndexSummaryReducer implements ForEachReducer {
    public function reduce( array $state, array $for_each ): array {
        return [
            'indexed_count' => count( $for_each['results'] ),
            'winning_url' => $for_each['winner']['output']['url'] ?? null,
        ];
    }
}

Η έξοδος του reducer συγχωνεύεται στην κατάσταση της ροής εργασίας όπως κάθε άλλη έξοδος βήματος. Μπορεί επίσης να επιστρέψει το _next_step για διακλάδωση μετά την ολοκλήρωση του for-each.

Συμπεριφορά επανάληψης

Οι διακλαδώσεις for-each επαναλαμβάνονται ανεξάρτητα, σύμφωνα με το config() του χειριστή διακλάδωσης. Αν αποτύχει το βήμα for-each και καλέσετε το retry_workflow(), το Queuety επεκτείνει ξανά το βήμα for-each και επαναθέτει στην ουρά μόνο τις διακλαδώσεις που εξακολουθούν να λείπουν ή να έχουν αποτύχει. Τα αποτελέσματα των επιτυχημένων διακλαδώσεων παραμένουν στην κατάσταση της ροής εργασίας.

Επιλογή μεταξύ parallel() και for_each()

Χρησιμοποιήστε το parallel() όταν η λίστα διακλαδώσεων είναι καθορισμένη στον κώδικα.

Χρησιμοποιήστε το for_each() όταν η λίστα διακλαδώσεων εντοπίζεται κατά την εκτέλεση από την κατάσταση της ροής εργασίας και χρειάζεστε λειτουργίες ολοκλήρωσης, όπως η πρώτη επιτυχία ή η απαρτία.