Μηχανές καταστάσεων
Οι μηχανές καταστάσεων και οι ροές εργασιών επιλύουν διαφορετικά προβλήματα.
Μια ροή εργασίας απαντά στο ερώτημα «ποια εργασία εκτελείται στη συνέχεια;». Μια μηχανή καταστάσεων απαντά στο ερώτημα «σε ποια κατάσταση βρίσκεται αυτό το στοιχείο και ποια συμβάντα είναι έγκυρα από εδώ και πέρα;». Αυτή η διαφορά έχει σημασία όταν αυτό που δημιουργείτε δεν είναι απλώς μια ακολουθία βημάτων, αλλά μια οντότητα με μεγάλο κύκλο ζωής που αντιδρά σε εξωτερικές εισόδους με την πάροδο του χρόνου, όπως μια συνεδρία agent, ένα νήμα συνομιλίας, ένας κύκλος αναθεώρησης, ένα αίτημα υποστήριξης ή μια ροή εγκρίσεων.
Γρήγορο παράδειγμα
use Queuety\Enums\StateMachineStatus;
use Queuety\Queuety;
$machine_id = Queuety::machine( 'agent_session' )
->version( 'agent-session.v1' )
->state( 'awaiting_user' )
->on( 'user_message', 'planning' )
->state( 'planning' )
->action( PlanSessionAction::class )
->on( 'planned', 'awaiting_review' )
->state( 'awaiting_review' )
->on( 'approve', 'completed', ReviewApprovedGuard::class )
->on( 'reject', 'awaiting_user' )
->state( 'completed', StateMachineStatus::Completed )
->dispatch( [ 'thread_id' => 42 ] );
Queuety::machine_event(
$machine_id,
'user_message',
[ 'message' => 'Find competitors for this product' ]
);
Queuety::machine_event(
$machine_id,
'approve',
[ 'approved' => true, 'reviewer' => 'editor@example.com' ]
);
Αυτή η μηχανή ξεκινά στο awaiting_user, μεταβαίνει στο planning όταν φτάνει ένα μήνυμα χρήστη, επιτρέπει στην ενέργεια της ουράς να εκπέμψει planned και έπειτα περιμένει στο awaiting_review μέχρι μια εξωτερική έγκριση να ολοκληρώσει τη συνεδρία. Το σημαντικό δεν είναι μόνο η σύνταξη του κώδικα. Είναι ότι ο κύκλος ζωής είναι ρητός, επιθεωρήσιμος και καθοδηγείται από συμβάντα.
Πώς εκτελείται μια μηχανή
Όταν αποστέλλεται ένα στιγμιότυπο μηχανής, το Queuety αποθηκεύει μόνιμα το τρέχον όνομα κατάστασης, το δημόσιο ωφέλιμο φορτίο κατάστασης, την έκδοση και το hash του ορισμού, τα έγκυρα εισερχόμενα συμβάντα για την τρέχουσα κατάσταση και ένα μόνιμο χρονολόγιο συμβάντων.
Αν η κατάσταση στην οποία εισέρχεται έχει ένα action(), το Queuety τοποθετεί μια εργασία εισόδου κατάστασης στην ουρά. Αυτή η ενέργεια μπορεί απλώς να ενημερώσει τη δημόσια κατάσταση και να αφήσει τη μηχανή σε αναμονή για το επόμενο συμβάν ή να εκπέμψει το _event και προαιρετικά το _event_payload, ώστε να προχωρήσει αμέσως στην επόμενη μετάβαση. Αν η κατάσταση δεν έχει ενέργεια ούτε τερματική κατάσταση, η μηχανή απλώς περιμένει εξωτερικά συμβάντα που αποστέλλονται με το Queuety::machine_event().
Επιλογή μεταξύ ροών εργασιών και μηχανών καταστάσεων
Χρησιμοποιήστε μια ροή εργασίας όταν η εκτέλεση βασίζεται ουσιαστικά σε βήματα. Λήψη δεδομένων, εργασία για κάθε στοιχείο, αναμονή, σύνθεση, ολοκλήρωση. Αυτό το μοντέλο ταιριάζει όταν υπάρχει σαφής αρχή και τέλος και το βασικό ερώτημα είναι ποια εργασία πρέπει να εκτελεστεί στη συνέχεια.
Χρησιμοποιήστε μια μηχανή καταστάσεων όταν η έγκυρη συμπεριφορά εξαρτάται από την τρέχουσα φάση του κύκλου ζωής. Ταιριάζει καλύτερα όταν τα συμβάντα μπορεί να φτάσουν με διαφορετική σειρά, όταν η οντότητα μπορεί να υπάρχει για μεγάλο χρονικό διάστημα ή όταν χρειάζεστε ρητή επιθεώρηση του κύκλου ζωής με καταστάσεις όπως awaiting_user, planning, running_agents, awaiting_review και completed.
Πώς συνεργάζονται τα δύο
Οι δύο μηχανισμοί λειτουργούν καλύτερα μαζί παρά ανταγωνιστικά. Μια ενέργεια κατάστασης μπορεί να αποστείλει μια ροή εργασίας όταν μια μετάβαση απαιτεί πιο σύνθετη εκτέλεση, ενώ μια ροή εργασίας μπορεί να εκπέμψει ένα συμβάν πίσω σε μια μηχανή όταν ολοκληρωθεί αυτή η εργασία. Στην πράξη, έτσι η μηχανή καταστάσεων διαχειρίζεται τον κύκλο ζωής, ενώ οι ροές εργασιών εκτελούν τις δαπανηρές ή ιδιαίτερα δομημένες εργασίες.
Δομή του εργαλείου δημιουργίας
Το StateMachineBuilder παραμένει σκόπιμα μικρό. Τα initial() και state() ορίζουν το γράφημα κύκλου ζωής. Το action() συνδέει εργασίες στην ουρά με μία κατάσταση. Το on() δηλώνει ποια συμβάντα μπορούν να μεταφέρουν τη μηχανή στην επόμενη κατάσταση. Τα on_queue(), with_priority() και max_attempts() ελέγχουν τον τρόπο εκτέλεσης των ενεργειών κατάστασης, ενώ τα version() και idempotency_key() επισυνάπτουν μόνιμα μεταδεδομένα αποστολής. Το dispatch() δημιουργεί το στιγμιότυπο της μηχανής.
Οι ενέργειες κατάστασης μπορούν επίσης να παρέχουν μια προαιρετική μέθοδο config(), χρησιμοποιώντας τα ίδια κλειδιά πολιτικής πόρων με τα βήματα και τους χειριστές ροών εργασιών. Έτσι, μια δαπανηρή μετάβαση κατάστασης μπορεί να ενταχθεί σε κοινή ομάδα ταυτόχρονης εκτέλεσης ή να της αποδοθεί μεγαλύτερο βάρος κόστους, όταν μια ενέργεια καταναλώνει περισσότερο προϋπολογισμό από ένα κανονικό βήμα.
Το ευρύτερο μοντέλο πόρων περιγράφεται στην ενότητα Διαχείριση πόρων.
Συμβόλαια
Οι ενέργειες εισόδου κατάστασης υλοποιούν το Queuety\Contracts\StateAction:
namespace Queuety\Contracts;
interface StateAction {
public function handle( array $state, ?string $event = null, array $event_payload = [], array $payload = [] ): array|string;
}
Το $payload είναι το δομημένο ωφέλιμο φορτίο από τον ορισμό της ενέργειας και είναι κενό όταν η ενέργεια δόθηκε ως απλό όνομα κλάσης. Το Queuety δημιουργεί ενέργειες με new $class(), επομένως μια κλάση ενέργειας χρειάζεται κατασκευαστή χωρίς υποχρεωτικά ορίσματα.
Οι ενέργειες κατάστασης μπορούν επίσης να ορίσουν μια προαιρετική μέθοδο config() με τα concurrency_group, concurrency_limit και cost_units, όταν η ενέργεια εισόδου που βρίσκεται στην ουρά πρέπει να συμμετέχει στην εισαγωγή εργαζομένων, στους προϋπολογισμούς ουρών ή παρόχων με σταθμισμένο κόστος και σε άλλες πολιτικές πόρων.
Οι φρουροί μετάβασης υλοποιούν το Queuety\Contracts\StateGuard:
namespace Queuety\Contracts;
interface StateGuard {
public function allows( array $state, array $event_payload, string $event, array $payload = [] ): bool;
}
API επιθεώρησης
Χρησιμοποιήστε το facade για να επιθεωρήσετε τις μηχανές που εκτελούνται:
$status = Queuety::machine_status( $machine_id );
$machines = Queuety::list_machines();
$events = Queuety::machine_timeline( $machine_id );
$trace = Queuety::machine_trace( $machine_id );
$state = Queuety::machine_state_at( $machine_id, $event_id );
Οι μηχανές καταστάσεων δεν διαθέτουν εντολές WP-CLI: το wp queuety workflow ... καλύπτει μόνο τις ροές εργασιών. Χρησιμοποιήστε αυτά τα API PHP, για παράδειγμα μέσω του wp eval, για να επιθεωρείτε μηχανές από τη γραμμή εντολών.
Αυτά τα API παρέχουν το τρέχον όνομα κατάστασης, την κατάσταση κύκλου ζωής, τη δημόσια κατάσταση, τα διαθέσιμα συμβάντα, τα μεταδεδομένα ορισμού, το πλήρες χρονολόγιο μεταβάσεων και ένα κανονικοποιημένο σύνολο ιχνών για τα περιβάλλοντα εργασίας εντοπισμού σφαλμάτων. Οι γραμμές της λίστας μηχανών περιλαμβάνουν την έκδοση ορισμού, το hash ορισμού και το κλειδί idempotency, ώστε οι οθόνες λίστας να εμφανίζουν την έκδοση πηγαίου κώδικα και εκτέλεσης χωρίς να φορτώνουν κάθε μηχανή ξεχωριστά. Το σύνολο ιχνών περιλαμβάνει ομαδοποιημένες καταστάσεις, ακατέργαστα συμβάντα, συσχετισμένες εργασίες ενεργειών, αρχεία καταγραφής, αναφορές τεχνουργημάτων, αναφορές τμημάτων, είσοδο και έξοδο χειριστών, κατάσταση πριν και μετά, περιβάλλον, χρονισμούς και δομημένα σφάλματα.
Συνεδρίες agent
Οι μηχανές καταστάσεων είναι ιδιαίτερα χρήσιμες για συστήματα agent που λειτουργούν περισσότερο ως συνεδρίες παρά ως αγωγοί επεξεργασίας. Μια συνεδρία που κινείται μεταξύ των awaiting_user, planning, running_agents, awaiting_review και completed είναι συνήθως ευκολότερο να γίνει κατανοητή ως ρητός κύκλος ζωής παρά ως ένας πολύ μεγάλος ορισμός ροής εργασίας με πολλές αναμονές και επιστροφές.