
# Tilakoneet

Tilakoneet ja työnkulut ratkaisevat eri ongelmia.

Työnkulku vastaa kysymykseen ”mitä työtä suoritetaan seuraavaksi?” Tilakone vastaa kysymykseen ”missä tilassa tämä asia on, ja mitkä tapahtumat ovat tästä tilasta sallittuja?” Ero on tärkeä, kun rakennettava asia ei ole vain vaiheiden sarja vaan pitkäikäinen kokonaisuus, joka reagoi ulkoiseen syötteeseen ajan mittaan, kuten agentin istunto, keskusteluketju, tarkistusprosessi, tiketti tai hyväksyntäprosessi.

## Pikaesimerkki

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

Tämä kone alkaa tilasta `awaiting_user`, siirtyy tilaan `planning` käyttäjän viestin saapuessa, antaa jonotetun toiminnon tuottaa arvon `planned` ja odottaa sitten tilassa `awaiting_review`, kunnes ulkoinen hyväksyntä päättää istunnon. Olennaista ei ole pelkkä koodin syntaksi, vaan se, että elinkaari on eksplisiittinen, tarkasteltavissa ja tapahtumaohjattu.

## Miten kone toimii

Kun kone-esiintymä lähetetään, Queuety tallentaa nykyisen tilan nimen, julkisen tilahyötykuorman, määritelmän version ja tiivisteen, nykyiseen tilaan saapuvat sallitut tapahtumat sekä pysyvän tapahtuma-aikajanan.

Jos siirryttävällä tilalla on `action()`, Queuety asettaa tilaan siirtymisen työn jonoon. Toiminto voi vain päivittää julkisen tilan ja jättää koneen odottamaan seuraavaa tapahtumaa, tai se voi tuottaa arvon `_event` ja valinnaisesti arvon `_event_payload` seuraavan siirtymän käynnistämiseksi heti. Jos tilalla ei ole toimintoa eikä päättävää tilaa, kone vain odottaa ulkoisia tapahtumia, jotka lähetetään `Queuety::machine_event()`-metodilla.

## Työnkulkujen ja tilakoneiden valinta

Käytä työnkulkua, kun suoritus koostuu pohjimmiltaan vaiheista: hae tiedot, odota kutakin työtehtävää, kokoa tulokset ja viimeistele. Tämä malli sopii tilanteeseen, jossa aloitus ja lopetus ovat selkeät ja keskeinen kysymys on, mikä työ suoritetaan seuraavaksi.

Käytä tilakonetta, kun sallitut toiminnot riippuvat elinkaaren nykyisestä vaiheesta. Se sopii paremmin, kun tapahtumat voivat saapua eri järjestyksissä, kokonaisuus voi olla pitkäikäinen tai tarvitset elinkaaren tilojen nimenomaista tarkastelua, esimerkiksi tiloissa `awaiting_user`, `planning`, `running_agents`, `awaiting_review` ja `completed`.

## Miten nämä kaksi toimivat yhdessä

Nämä kaksi perusosaa toimivat parhaiten yhdessä, eivät toisiaan vastaan kilpaillen. Tilan toiminto voi lähettää työnkulun, kun siirtymä vaatii raskaampaa suoritusta, ja työnkulku voi lähettää tapahtuman takaisin koneeseen työn valmistuttua. Näin tilakone hallitsee elinkaarta, kun taas työnkulut suorittavat raskaat tai tarkasti jäsennellyt tehtävät.

## Koostajan rakenne

`StateMachineBuilder` on tarkoituksella pieni. `initial()` ja `state()` määrittelevät elinkaarikaavion. `action()` liittää jonotetun työn yhteen tilaan. `on()` määrittää, mitkä tapahtumat voivat siirtää koneen seuraavaan tilaan. `on_queue()`, `with_priority()` ja `max_attempts()` ohjaavat tilan toimintojen suoritusta, kun taas `version()` ja `idempotency_key()` liittävät lähetykseen pysyvät metatiedot. `dispatch()` luo kone-esiintymän.

Tilatoiminnot voivat myös tarjota valinnaisen `config()`-metodin samoilla resurssikäytännön avaimilla, joita työnkulun vaiheet ja käsittelijät käyttävät. Näin kallis tilasiirtymä voidaan sijoittaa jaettuun samanaikaisuusryhmään tai sille voidaan määrittää suurempi kustannuspaino, kun toiminto kuluttaa enemmän budjettia kuin tavallinen vaihe.

Laajempi resurssimalli kuvataan kohdassa [Resurssien hallinta](https://queuety.inline0.dev/fi/docs/features/resource-management).

## Sopimukset

Tilaan siirtymisen toiminnot toteuttavat `Queuety\Contracts\StateAction`-rajapinnan:

```php
namespace Queuety\Contracts;

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

`$payload` on jäsennelty hyötykuorma toiminnon määritelmästä, ja se on tyhjä, jos toiminto annettiin pelkkänä luokan nimenä. Queuety luo toimintoja käyttäen `new $class()`-metodia, joten toimintoluokan konstruktorissa ei saa olla pakollisia argumentteja.

Tilatoiminnot voivat määrittää myös valinnaisen `config()`-metodin parametreilla `concurrency_group`, `concurrency_limit` ja `cost_units`, kun jonotetun tilaan siirtymisen toiminnon halutaan osallistuvan työntekijän pääsynhallintaan, painotettuihin jonoihin tai palveluntarjoajabudjetteihin ja muihin resurssikäytäntöihin.

Siirtymän ehtojen tarkistajat toteuttavat `Queuety\Contracts\StateGuard`-rajapinnan:

```php
namespace Queuety\Contracts;

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

## Tarkastelurajapinnat

Tarkastele käynnissä olevia koneita julkisivun kautta:

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

Tilakoneilla ei ole WP-CLI-komentoja: `wp queuety workflow ...` kattaa vain työnkulut. Voit tarkastella koneita komentoriviltä näiden PHP-rajapintojen avulla, esimerkiksi käyttämällä `wp eval`-työkalua.

Nämä rajapinnat näyttävät nykyisen tilan nimen, elinkaaren tilan, julkisen tilan, käytettävissä olevat tapahtumat, määritelmän metatiedot, koko siirtymäaikajanan ja debuggerien käyttöliittymille tarkoitetun normalisoidun jälkipaketin. Koneluettelon riveillä näkyvät määritelmän versio, tiiviste ja idempotenssiavain, joten luettelonäkymät voivat näyttää lähde- ja suorituksenaikaisen version lataamatta jokaista konetta erikseen. Jälkipaketti sisältää ryhmitellyt tilat, raakamuotoiset tapahtumat, toisiinsa liitetyt toimintotyöt, lokit, artefaktiviittaukset, lohkoviittaukset, käsittelijän syötteen ja tulosteen, tilan ennen suoritusta ja sen jälkeen, kontekstin, ajoitukset sekä jäsennellyt virheet.

## Agentti-istunnot

Tilakoneet ovat erityisen hyödyllisiä agenttijärjestelmissä, jotka muistuttavat enemmän istuntoja kuin käsittelyputkia. Istunto, joka siirtyy tilojen `awaiting_user`, `planning`, `running_agents`, `awaiting_review` ja `completed` kautta, on yleensä helpompi hahmottaa eksplisiittisenä elinkaarena kuin yhtenä hyvin pitkänä työnkulkumäärittelynä, jossa on paljon odotuksia ja paluusiirtymiä.

## Katso myös

- [Neuron Istunnon tilakone](https://queuety.inline0.dev/fi/docs/examples/neuron-session-state-machine)
- [Neuron Muistin ja tarkistuksen tilakone](https://queuety.inline0.dev/fi/docs/examples/neuron-memory-review)
- [Agenttien orkestrointi](https://queuety.inline0.dev/fi/docs/workflows/agent-orchestration)
- [Työnkulun signaalit](https://queuety.inline0.dev/fi/docs/workflows/signals)
- [Työnkulun riippuvuudet](https://queuety.inline0.dev/fi/docs/workflows/dependencies)
- [Toistot](https://queuety.inline0.dev/fi/docs/workflows/repeats)
- [Artefaktit](https://queuety.inline0.dev/fi/docs/features/artifacts)
- [PHP API](https://queuety.inline0.dev/fi/docs/api)
