
# 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](https://queuety.inline0.dev/sl/docs/features/resource-management).

## 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

- [Neuron Stroj stanj seje](https://queuety.inline0.dev/sl/docs/examples/neuron-session-state-machine)
- [Neuron Stroj stanj za pomnilnik in pregled](https://queuety.inline0.dev/sl/docs/examples/neuron-memory-review)
- [Orkestracija agentov](https://queuety.inline0.dev/sl/docs/workflows/agent-orchestration)
- [Signali delovnega toka](https://queuety.inline0.dev/sl/docs/workflows/signals)
- [Odvisnosti delovnega toka](https://queuety.inline0.dev/sl/docs/workflows/dependencies)
- [Ponovitve](https://queuety.inline0.dev/sl/docs/workflows/repeats)
- [Artefakti](https://queuety.inline0.dev/sl/docs/features/artifacts)
- [PHP API](https://queuety.inline0.dev/sl/docs/api)
