Preskoči na vsebino

Avtomati stanj

Avtomati stanj in delovni tokovi rešujejo različne težave.

Delovni tok odgovarja na vprašanje: »katero delo se izvede naslednje?« Avtomat stanj pa odgovarja: »v kakšnem stanju je ta stvar in kateri dogodki so od tu naprej dovoljeni?« Ta razlika je pomembna, kadar ne gradite le zaporedja korakov, temveč dolgotrajno entiteto, ki se sčasoma odziva na zunanje vnose, na primer sejo agenta, nit klepeta, življenjski cikel pregleda, zahtevek ali postopek odobritve.

Kratek primer

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

Ta avtomat se začne v awaiting_user, ob prejemu uporabnikovega sporočila preide v planning, omogoči, da dejanje v čakalni vrsti odda planned, nato pa čaka v awaiting_review, dokler zunanja odobritev ne zaključi seje. Bistvo ni zgolj v sintaksi kode. Pomembno je, da je življenjski cikel izrecen, pregledljiv in voden z dogodki.

Kako deluje avtomat

Ko je primerek avtomata poslan, Queuety shrani trenutno ime stanja, javno vsebino stanja, različico in zgoščeno vrednost definicije, veljavne vhodne dogodke za trenutno stanje ter trajno časovnico dogodkov.

Če ima vstopno stanje action(), Queuety doda opravilo za vstop v stanje v čakalno vrsto. To dejanje lahko zgolj posodobi javno stanje in pusti avtomat čakati na naslednji dogodek ali pa odda _event in po želji _event_payload za takojšen naslednji prehod. Če stanje nima dejanja in ni končno, avtomat samo čaka na zunanje dogodke, poslane z Queuety::machine_event().

Izbira med delovnimi tokovi in avtomati stanj

Delovni tok uporabite, kadar je izvajanje zasnovano predvsem kot zaporedje korakov. Pridobite podatke, za vsako delo počakajte, združite rezultate in zaključite. Ta model je primeren, kadar sta začetek in konec jasna, glavno vprašanje pa je, katero delo naj se izvede naslednje.

Avtomat stanj uporabite, kadar je veljavno vedenje odvisno od trenutne faze življenjskega cikla. Primernejši je, kadar lahko dogodki prispejo v različnem vrstnem redu, kadar entiteta obstaja dolgo časa ali kadar potrebujete izrecen pregled življenjskega cikla s stanji, kot so awaiting_user, planning, running_agents, awaiting_review in completed.

Kako delujeta skupaj

Oba osnovna gradnika najbolje delujeta skupaj, ne tekmujeta drug z drugim. Dejanje stanja lahko pošlje delovni tok, kadar prehod zahteva zahtevnejše izvajanje, delovni tok pa lahko po končanem delu odda dogodek nazaj v avtomat. Tako avtomat stanj v praksi upravlja življenjski cikel, delovni tokovi pa izvajajo zahtevno ali zelo strukturirano delo.

Zasnova gradnika

StateMachineBuilder je namenoma majhen. initial() in state() določata graf življenjskega cikla. action() pripne delo v čakalni vrsti enemu stanju. on() določa, kateri dogodki lahko premaknejo avtomat v naslednje stanje. on_queue(), with_priority() in max_attempts() nadzorujejo izvajanje dejanj stanja, medtem ko version() in idempotency_key() pripneta trajne metapodatke pošiljanja. dispatch() ustvari primerek avtomata.

Dejanja stanja lahko razkrijejo tudi neobvezno metodo config() z enakimi ključi pravilnikov o virih, kot jih uporabljajo koraki in obravnavalniki delovnih tokov. Tako je mogoče en zahteven prehod stanja ohraniti v skupni skupini za sočasnost ali mu določiti večjo utež stroškov, kadar dejanje porabi več proračuna kot običajen korak.

Širši model virov je opisan v razdelku Upravljanje virov.

Pogodbe

Dejanja ob vstopu v stanje implementirajo Queuety\Contracts\StateAction:

PHP
namespace Queuety\Contracts;

interface StateAction {
    public function handle( array $state, ?string $event = null, array $event_payload = [], array $payload = [] ): array|string;
}

$payload je strukturirana vsebina iz definicije dejanja; prazna je, kadar je bilo dejanje podano kot navadno ime razreda. Queuety ustvarja dejanja z new $class(), zato razred dejanja potrebuje konstruktor brez obveznih argumentov.

Dejanja stanja lahko določijo tudi neobvezno metodo config() z concurrency_group, concurrency_limit in cost_units, kadar mora dejanje ob vstopu v stanje, dodano v čakalno vrsto, sodelovati pri sprejemanju opravil s strani delavcev, uteženih proračunih čakalnih vrst ali ponudnikov ter drugih pravilnikih o virih.

Pogoji prehoda implementirajo Queuety\Contracts\StateGuard:

PHP
namespace Queuety\Contracts;

interface StateGuard {
    public function allows( array $state, array $event_payload, string $event, array $payload = [] ): bool;
}

API-ji za pregled

Za pregled delujočih avtomatov uporabite fasado:

PHP
$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 );

Avtomati stanj nimajo ukazov WP-CLI: wp queuety workflow ... pokriva samo delovne tokove. Za pregled avtomatov iz ukazne vrstice uporabite te API-je PHP, na primer prek wp eval.

Ti API-ji razkrivajo trenutno ime stanja, stanje življenjskega cikla, javno stanje, razpoložljive dogodke, metapodatke definicije, celotno časovnico prehodov in normaliziran sveženj sledi za uporabniške vmesnike za odpravljanje napak. Vrstice seznama avtomatov vključujejo različico definicije, zgoščeno vrednost definicije in ključ idempotentnosti, tako da lahko zasloni s seznami prikažejo izvorno oziroma izvajalno različico, ne da bi morali vsak avtomat naložiti posebej. Sveženj sledi vključuje združena stanja, surove dogodke, povezana opravila dejanj, dnevnike, sklice na artefakte, sklice na dele, vhodne in izhodne podatke obravnavalnika, stanje pred in po, kontekst, čase ter strukturirane napake.

Seje agentov

Avtomati stanj so posebej uporabni za sisteme agentov, ki so bolj podobni sejam kot cevovodom. Sejo, ki se premika med awaiting_user, planning, running_agents, awaiting_review in completed, je običajno lažje razumeti kot izrecen življenjski cikel kot pa kot eno zelo dolgo definicijo delovnega toka s številnimi čakanji in povratnimi povezavami.

Glejte tudi