
# PHP API

Kaikki Queuety-ominaisuudet ovat käytettävissä staattisen `Queuety\Queuety`-luokan kautta. Se on ainoa sisääntulopiste tehtävien jakeluun, työnkulkujen rakentamiseen, tilakoneiden ohjaukseen, jonojen hallintaan ja sisäisten alijärjestelmien käyttöön.

```php
use Queuety\Queuety;
```

## Itsenäinen ydintoimintojen käyttö

Queuetyn tietokantapohjaisen ajonaikaisen ympäristön voi alustaa myös WordPressn ulkopuolella.

Itsenäinen käyttötapa on tarkoitettu orkestroinnin ydinominaisuuksille:

- tehtävät ja työntekijät (työntekijäpoolit tarvitsevat myös vakiot `DB_HOST`, `DB_NAME`, `DB_USER` ja `DB_PASSWORD`; katso alta)
- työnkulut ja signaalit
- tilakoneet ja tapahtumat
- artefaktit, lokit, mittarit ja aikataulut

Se ei korvaa sovitinta WordPress. `Queuety::on_action()`,
`replace_wp_cron()`, lisäosan käynnistys ja varsinainen `wp queuety ...`n
rekisteröintipolku edellyttävät edelleen WordPressa.

### `Queuety::init( Connection $conn )`

Alusta Queuety suoralla tietokantayhteydellä.

```php
use Queuety\Connection;
use Queuety\Queuety;

$conn = new Connection(
    host: '127.0.0.1:3306',
    dbname: 'wordpress',
    user: 'root',
    password: 'secret',
    prefix: 'wp_',
);

Queuety::init( $conn );
```

Valinnainen argumentti `table_prefix` muuttaa yhteyskohtaisesti ajonaikaisen ympäristön taulukoiden nimien Queuety-osan:

```php
$conn = new Connection(
    host: '127.0.0.1:3306',
    dbname: 'wordpress',
    user: 'root',
    password: 'secret',
    prefix: 'wp_',
    table_prefix: 'themequeue_',
);
```

Tämä ratkaisee esimerkiksi taulut `queuety_jobs`–`wp_themequeue_jobs`.

### `Queuety::ensure_schema()`

Varmista, että aktiiviselle yhteydelle on määritetty Queuety-ajonaikataulut.

```php
Queuety::init( $conn );
Queuety::ensure_schema();
```

Katso koko malli ja WordPress-raja kohdasta [Itsenäinen käyttö](https://queuety.inline0.dev/fi/docs/features/standalone-use).

## Työt

### `Queuety::dispatch( $handler, $payload )`

Lähetä työ suoritettavaksi. Hyväksyy joko käsittelijän nimen merkkijonona tai `Contracts\Job`-ilmentymän. Palauttaa `PendingJob`-rakentajan, jolla voit ketjuttaa valintoja.

```php
// Handler name + payload (original API)
Queuety::dispatch( 'send_email', [ 'to' => 'user@example.com' ] );

// Contracts\Job instance (v0.6.0+)
Queuety::dispatch( new SendEmailJob( to: 'user@example.com' ) );

// With options
Queuety::dispatch( 'send_email', [ 'to' => 'user@example.com' ] )
    ->on_queue( 'emails' )
    ->with_priority( Priority::High )
    ->delay( 300 )
    ->max_attempts( 5 )
    ->rate_limit( 10, 60 )
    ->unique()
    ->after( $other_job_id );

// Get the job ID
$job_id = Queuety::dispatch( 'send_email', $payload )->id();
```

Kun välitetään `Contracts\Job`-ilmentymä, sarjoitin poimii FQCN:n käsittelijän nimeksi ja julkiset ominaisuudet hyötykuormaksi. Parametria `$payload` ei huomioida, kun `$handler` on `Job`-ilmentymä.

### `PendingJob`-metodit

| Metodi | Kuvaus |
|---|---|
| `on_queue( string $queue )` | Aseta kohdejono |
| `with_priority( Priority $priority )` | Aseta prioriteettitaso |
| `delay( int $seconds )` | Viive ennen kuin työ on käytettävissä |
| `max_attempts( int $max )` | Uudelleenyritysten enimmäismäärä |
| `rate_limit( int $max, int $window )` | Nopeusrajoitus: suoritusten enimmäismäärä aikaikkunan sekunteina ilmaistuna |
| `unique()` | Estä kaksoislähetykset |
| `after( int $job_id )` | Odota, että toinen työ valmistuu ensin |
| `concurrency_group( string $group, int $limit )` | Sijoita työ jaettuun työntekijöiden hyväksyntäryhmään |
| `cost_units( int $units )` | Liitä lähetykseen suhteelliset suoritus-kustannustiedot |
| `id()` | Pakota lähetys ja palauta työn tunnus |

`concurrency_group()` ja `cost_units()` täydentävät laajempaa [Resurssienhallinta](https://queuety.inline0.dev/fi/docs/features/resource-management)-mallia, joten sama lähetys voi osallistua määrään perustuviin samanaikaisuusrajoituksiin, painotettuihin jono- tai palveluntarjoajakohtaisiin budjetteihin sekä työntekijöiden hyväksyntää koskeviin heuristiikkoihin.

### `Queuety::dispatch_sync( $handler, $payload )`

Suorita työ synkronisesti nykyisessä prosessissa lisäämättä sitä jonoon.

```php
// With a Job instance
Queuety::dispatch_sync( new SendEmailJob( to: 'user@example.com', subject: 'Hi', body: 'Hello' ) );

// With a handler name and payload
Queuety::dispatch_sync( 'send_email', [ 'to' => 'user@example.com' ] );
```

Työn `handle()`-metodia kutsutaan suoraan. Tietokantariviä ei luoda, työntekijää ei käytetä eikä väliohjelmistoa sovelleta.

### `Queuety::batch( $jobs )`

Lähetä useita töitä yhdellä usean rivin INSERT-lauseella.

```php
$job_ids = Queuety::batch( [
    [ 'handler' => 'send_email', 'payload' => [ 'to' => 'a@example.com' ], 'queue' => 'emails' ],
    [ 'handler' => 'send_email', 'payload' => [ 'to' => 'b@example.com' ], 'priority' => 2 ],
] );
```

### `Queuety::create_batch( $jobs )`

Luo `BatchBuilder` töiden ryhmän lähettämiseen sekä takaisinkutsujen ja edistymisen seurantaan. Katso kaikki tiedot kohdasta [Eräkäsittely](https://queuety.inline0.dev/fi/docs/features/batching).

```php
$batch = Queuety::create_batch( [
    new ImportUsersJob( $chunk_1 ),
    new ImportUsersJob( $chunk_2 ),
] )
    ->name( 'Import users' )
    ->then( ImportCompleteHandler::class )
    ->catch( ImportFailedHandler::class )
    ->finally( ImportCleanupHandler::class )
    ->allow_failures()
    ->on_queue( 'imports' )
    ->dispatch();
```

### `BatchBuilder`-metodit

| Metodi | Palauttaa | Kuvaus |
|---|---|---|
| `name( string $name )` | `self` | Aseta erälle nimi |
| `on_queue( string $queue )` | `self` | Aseta jono kaikille erän töille |
| `then( string $handler_class )` | `self` | Käsittelijä, jota kutsutaan, kun erä valmistuu onnistuneesti |
| `catch( string $handler_class )` | `self` | Käsittelijä, jota kutsutaan, kun erän ensimmäinen työ epäonnistuu |
| `finally( string $handler_class )` | `self` | Käsittelijä, jota kutsutaan, kun erä valmistuu (onnistuneesti tai epäonnistuen) |
| `allow_failures()` | `self` | Salli `then`-takaisinkutsun suoritus myös epäonnistumisten yhteydessä |
| `dispatch()` | `Batch` | Luo erärivi ja kaikki työt; palauttaa `Batch`-arvo-olion |

### `Queuety::find_batch( $id )`

Hae erä tunnuksen perusteella. Palauttaa `Batch`-arvo-olion tai `null`.

```php
$batch = Queuety::find_batch( $batch_id );

if ( null !== $batch ) {
    echo $batch->progress() . '% complete';
}
```

## Työntekijöiden hallinta

### `Queuety::run_worker( $queue = 'default', $once = false )`

Suorita yksi työntekijän silmukka suoraan.

```php
Queuety::run_worker( 'default' );
Queuety::run_worker( 'critical,default', true );
```

### `Queuety::run_worker_pool( $workers, $queue = 'default' )`

Suorita kiinteän kokoinen työntekijäpooli suoraan. Edellyttää laajennuksia `pcntl` ja `posix`. Pooli lukee alitason yhteyksilleen vakiot WordPress `DB_HOST`, `DB_NAME`, `DB_USER` ja `DB_PASSWORD` (vain taulujen etuliitteet tulevat alustetulta yhteydeltä), joten määritä ne, kun suoritat poolin WordPress-ympäristön ulkopuolella ([#5](https://github.com/inline0/queuety/issues/5)).

```php
Queuety::run_worker_pool( 4, 'providers' );
```

### `Queuety::run_auto_scaling_worker_pool( $min_workers, $max_workers, $queue = 'default' )`

Suorita mukautuva työntekijäpooli suoraan. Samat vaatimukset kuin kohdassa `run_worker_pool()`.

```php
Queuety::run_auto_scaling_worker_pool( 2, 6, 'providers' );
```

### `Batch`-arvo-olio

| Metodi/ominaisuus | Tyyppi | Kuvaus |
|---|---|---|
| `$id` | `int` | Erän tunnus |
| `$name` | `string\|null` | Valinnainen erän nimi |
| `$total_jobs` | `int` | Erän töiden kokonaismäärä |
| `$pending_jobs` | `int` | Vielä odottavat työt |
| `$failed_jobs` | `int` | Epäonnistuneiden töiden määrä |
| `$failed_job_ids` | `array` | Epäonnistuneiden töiden tunnukset |
| `$created_at` | `DateTimeImmutable` | Erän luontiaika |
| `$finished_at` | `DateTimeImmutable\|null` | Erän valmistumisaika |
| `$cancelled_at` | `DateTimeImmutable\|null` | Erän peruutusaika |
| `progress()` | `int` | Valmistumisprosentti (0–100) |
| `finished()` | `bool` | Onko erä valmis |
| `has_failures()` | `bool` | Epäonnistuiko jokin työ |
| `cancelled()` | `bool` | Peruutettiinko erä |

### `Queuety::chain( $jobs )`

Luo `ChainBuilder` peräkkäisten töiden suorittamiseen. Kukin työ riippuu siitä, että edellinen valmistuu onnistuneesti.

```php
$first_job_id = Queuety::chain( [
    new FetchDataJob( $url ),
    new ProcessDataJob(),
    new NotifyCompleteJob(),
] )
    ->on_queue( 'pipeline' )
    ->catch( ChainFailedHandler::class )
    ->dispatch();
```

### `ChainBuilder`-metodit

| Metodi | Palauttaa | Kuvaus |
|---|---|---|
| `on_queue( string $queue )` | `self` | Aseta jono kaikille ketjun töille |
| `catch( string $handler_class )` | `self` | Käsittelijä, jota kutsutaan, kun jokin ketjun työ haudataan pysyvästi |
| `dispatch()` | `int` | Luo kaikki työt peräkkäisine riippuvuuksineen ja palauta ensimmäisen työn tunnus |

### `Queuety::retry( $job_id )`

Yritä tiettyä työtä uudelleen. Palauta sen tilaksi `pending`.

```php
Queuety::retry( 42 );
```

### `Queuety::retry_buried()`

Yritä uudelleen kaikkia haudattuja töitä. Palauttaa uudelleen yritettyjen töiden määrän.

```php
$count = Queuety::retry_buried();
```

### `Queuety::purge( $older_than_days )`

Poista valmistuneet työt. Palauttaa poistettujen töiden määrän.

```php
$count = Queuety::purge();     // uses QUEUETY_RETENTION_DAYS
$count = Queuety::purge( 30 ); // purge jobs older than 30 days
```

## Jonot

### `Queuety::stats( $queue )`

Hae töiden määrät tiloittain ryhmiteltyinä.

```php
$stats = Queuety::stats();          // all queues
$stats = Queuety::stats( 'emails' ); // specific queue
// ['pending' => 12, 'processing' => 3, 'completed' => 150, 'failed' => 2, 'buried' => 1]
```

### `Queuety::buried( $queue )`

Hae kaikki haudatut työt.

```php
$jobs = Queuety::buried();
$jobs = Queuety::buried( 'emails' );
```

### `Queuety::pause( $queue )`

Keskeytä jono, jotta työntekijät ohittavat sen.

```php
Queuety::pause( 'emails' );
```

### `Queuety::resume( $queue )`

Jatka keskeytettyä jonoa.

```php
Queuety::resume( 'emails' );
```

### `Queuety::is_paused( $queue )`

Tarkista, onko jono keskeytetty.

```php
if ( Queuety::is_paused( 'emails' ) ) {
    // Queue is paused
}
```

## Työnkulut

### `Queuety::workflow( $name )`

Aloita työnkulun rakentaminen. Palauttaa `WorkflowBuilder`-olion.

```php
$workflow_id = Queuety::workflow( 'generate_report' )
    ->then( FetchDataHandler::class )
    ->then( CallLLMHandler::class )
    ->then( FormatOutputHandler::class )
    ->dispatch( [ 'user_id' => 42 ] );
```

### `WorkflowBuilder`-metodit

| Metodi | Kuvaus |
|---|---|
| `then( string $handler_class, ?string $name = null )` | Lisää peräkkäinen vaihe. Valinnainen nimi ehdollista haarautumista varten. |
| `parallel( array $handler_classes )` | Lisää rinnakkaisten vaiheiden ryhmä. |
| `for_each( string $items_key, string $handler_class, ?string $result_key = null, ForEachMode $mode = ForEachMode::All, ?int $quorum = null, ?string $reducer_class = null, ?string $name = null )` | Lisää dynaaminen for-each-vaihe, joka laajentuu yhdeksi haaratyöksi työnkulun tilan kutakin kohdetta kohti. |
| `repeat_while( string $target_step, ?string $state_key = null, mixed $expected = true, ?string $name = null, ?string $condition_class = null, ?int $max_iterations = null )` | Siirry takaisin aiempaan nimettyyn vaiheeseen, kunnes julkinen tila-avain tai `RepeatCondition`-luokka vastaa ehtoa. |
| `repeat_until( string $target_step, ?string $state_key = null, mixed $expected = true, ?string $name = null, ?string $condition_class = null, ?int $max_iterations = null )` | Siirry takaisin aiempaan nimettyyn vaiheeseen, kunnes julkinen tila-avain tai `RepeatCondition`-luokka vastaa ehtoa. |
| `run_workflow( string $workflow_name, WorkflowBuilder $sub_builder )` | Lisää työnkulun suorittava vaihe. |
| `delay( int $seconds = 0, int $minutes = 0, int $hours = 0, int $days = 0 )` | Lisää pysyvä viivevaihe. Kaikki kestot lasketaan yhteen. |
| `wait_for_signal( string $name, ?string $result_key = null, ?string $step_name = null, array $match_payload = [], ?string $correlation_key = null )` | Lisää signaalin odotusvaihe. Valinnaisten asetusten `match_payload` ja `correlation_key` avulla voit ohittaa asiaankuulumattomat tapahtumat. |
| `wait_for_signals( array $signal_names, WaitMode $mode = WaitMode::All, ?string $result_key = null, ?string $name = null, array $match_payload = [], ?string $correlation_key = null )` | Odota, että useista signaaleista saapuvat kaikki tai jokin niistä; voit myös täsmäyttää hyötykuorman ja korrelaation. |
| `wait_for_approval( string $signal_name = 'approval', ?string $result_key = 'approval', ?string $name = null, array $match_payload = [], ?string $correlation_key = null )` | Odota ihmisen hyväksyntäsignaalia. |
| `wait_for_decision( string $approve_signal = 'approved', string $reject_signal = 'rejected', ?string $result_key = 'decision', ?string $name = null, array $match_payload = [], ?string $correlation_key = null )` | Odota hyväksyntää tai hylkäystä ja tallenna jäsennelty päätöshyötykuorma. |
| `wait_for_input( string $signal_name = 'input', ?string $result_key = 'input', ?string $name = null, array $match_payload = [], ?string $correlation_key = null )` | Odota ihmisen syötesignaalia. |
| `wait_for_workflow( int\|string $workflow, ?string $result_key = null, ?string $name = null )` | Odota yhden työnkulun tunnuksen tai julkiseen tilaan tallennetun työnkulun tunnuksen valmistumista. |
| `wait_for_workflows( array\|string $workflows, WaitMode $mode = WaitMode::All, ?string $result_key = null, ?string $name = null, ?int $quorum = null )` | Odota, että useat työnkulut valmistuvat kaikki tai jokin niistä tai että päätösvaltainen määrä niistä valmistuu. |
| `wait_for_workflow_group( string $group_key, WaitMode $mode = WaitMode::All, ?int $quorum = null, ?string $result_key = null, ?string $name = null )` | Odota aiemmin käynnistettyä työnkulkuryhmää sisäisen ryhmäavaimen perusteella. |
| `start_workflows( string $items_key, WorkflowBuilder $workflow_builder, string $result_key = 'started_workflow_ids', string $payload_key = 'item', bool $inherit_state = true, ?string $name = null, ?string $group_key = null )` | Lähetä yksi ylätason työnkulku kutakin ajonaikaista kohdetta kohti; voit halutessasi merkitä käynnistetyn joukon pysyvällä ryhmäavaimella. |
| `start_agents( string $items_key, WorkflowBuilder $workflow_builder, string $result_key = 'agent_workflow_ids', string $payload_key = 'agent_task', bool $inherit_state = true, ?string $name = null, ?string $group_key = null )` | Työnkulkuagentille tarkoitettu alias nimelle `start_workflows()`. |
| `wait_for_agents( array\|string $workflows = 'agent_workflow_ids', WaitMode $mode = WaitMode::All, ?string $result_key = 'agent_results', ?string $name = null, ?int $quorum = null )` | Työnkulkuagentille tarkoitettu alias nimelle `wait_for_workflows()`. |
| `wait_for_agent_group( string $group_key = 'agents', WaitMode $mode = WaitMode::All, ?int $quorum = null, ?string $result_key = 'agent_results', ?string $name = null )` | Työnkulkuagentille tarkoitettu alias nimelle `wait_for_workflow_group()`. |
| `version( string $version )` | Merkitse työnkulun määritelmään sovellustason versio tarkastelua ja vientiä varten. |
| `idempotency_key( string $key )` | Tee työnkulun lähetyksestä pysyvä kutsujan antamalla avaimella. Uusi lähetys samalla avaimella palauttaa alkuperäisen työnkulun tunnuksen. |
| `max_transitions( int $max )` | Epäonnista työnkulku, jos vaiheiden siirtymiä valmistuu yli `$max`. |
| `max_for_each_items( int $max )` | Epäonnista työnkulku, jos `for_each()`-vaihe yrittää laajentua yli `$max` kohteeksi. |
| `max_state_bytes( int $bytes )` | Epäonnista työnkulku, jos julkinen tila kasvaa yli koon `$bytes`. |
| `max_cost_units( int $max )` | Epäonnista työnkulku, jos valmistuneet vaiheet kuluttavat yli `$max` kustannusyksikköä. |
| `max_started_workflows( int $max )` | Epäonnista työnkulku, jos se yrittää lähettää yli `$max` alityönkulkua. |
| `compensate_with( string $handler_class )` | Liitä viimeksi lisättyyn vaiheeseen korvaava käsittelijä. |
| `compensate_on_failure()` | Suorita valmistuneiden vaiheiden korvaavat toiminnot automaattisesti työnkulun epäonnistuessa. |
| `on_queue( string $queue )` | Aseta jono kaikille vaiheille. |
| `with_priority( Priority $priority )` | Aseta prioriteetti kaikille vaiheille. |
| `max_attempts( int $max )` | Aseta vaihekohtainen uudelleenyritysten enimmäismäärä. |
| `on_cancel( string $handler_class )` | Rekisteröi peruutuksen siivouskäsittelijäluokka. Katso [Peruutus](https://queuety.inline0.dev/fi/docs/workflows/cancellation). |
| `prune_state_after( int $steps = 2 )` | Ota käyttöön tilan automaattinen karsiminen. Poistaa kynnysarvoa vanhemmat vaihetulokset. Katso [Tilan karsiminen](https://queuety.inline0.dev/fi/docs/features/state-pruning). |
| `must_complete_within( int $seconds = 0, int $minutes = 0, int $hours = 0, int $days = 0 )` | Aseta työnkululle määräaika. Kaikki kestot lasketaan yhteen. Katso [Määräajat](https://queuety.inline0.dev/fi/docs/workflows/deadlines). |
| `on_deadline( string $handler_class )` | Rekisteröi käsittelijä, jota kutsutaan työnkulun määräajan ylittyessä. Katso [Määräajat](https://queuety.inline0.dev/fi/docs/workflows/deadlines). |
| `dispatch( array $initial_payload = [] )` | Lähetä työnkulku. Palauttaa työnkulun tunnuksen. |

### `Queuety::workflow_status( $workflow_id )`

Hae työnkulun tila. Palauttaa `WorkflowState`-olion tai `null`.

```php
$state = Queuety::workflow_status( $workflow_id );
echo $state->name;          // 'generate_report'
echo $state->status->value; // 'running'
echo $state->current_step;  // 1
echo $state->total_steps;   // 3
print_r( $state->state );   // accumulated public state array
echo $state->wait_type;     // 'signal' or 'workflow' while blocked
echo $state->wait_mode;     // 'all', 'any', or 'quorum'
echo $state->definition_version; // 'research.v2'
echo $state->definition_hash;    // '4c7a...'
echo $state->idempotency_key;    // 'brief:42:research'
echo $state->artifact_count;     // 2
print_r( $state->budget );       // configured workflow budget + current usage
print_r( $state->wait_details ); // matched/remaining blockers, result key, correlation info
print_r( $state->artifact_keys ); // ['draft', 'citations']
```

`WorkflowState` sisältää myös seuraavat tiedot:

- `waiting_for`: signaalien nimet tai työnkulkujen tunnukset, jotka parhaillaan estävät suorituksen jatkumisen
- `current_step_name`: nykyisen vaiheen määritetty nimi, jos sellainen on
- `wait_mode`: nykyinen odotustila (`all`, `any` tai `quorum`), kun suoritus on estynyt
- `wait_details`: lisätarkastelutiedot, kuten täsmätyt ja jäljellä olevat estävät tekijät
- `definition_version`: arvon, jonka asetti `version()`, jos sellainen on
- `definition_hash`: työnkulun määritelmän deterministinen tiiviste
- `idempotency_key`: pysyvän lähetyksen avain, jos sellainen on
- `budget`: määritetyt rajat ja nykyinen käyttö, jos suojakaiteet ovat käytössä
- `artifact_count`: työnkululle tallennettujen artefaktien määrä
- `artifact_keys`: tallennettujen artefaktien avaimet nopeaa tarkastelua varten

### `Queuety::retry_workflow( $workflow_id )`

Yritä epäonnistunutta työnkulkua uudelleen sen epäonnistuneesta vaiheesta alkaen.

```php
Queuety::retry_workflow( $workflow_id );
```

Heittää `RuntimeException`-poikkeuksen, jos työnkulun virheen jälkeiset korvaavat toiminnot on jo suoritettu.

### `Queuety::pause_workflow( $workflow_id )`

Keskeytä käynnissä oleva työnkulku. Nykyiselle vaiheelle jo jonoon asetetut työt voivat vielä valmistua, mutta myöhempiä vaiheita ei aseteta jonoon ennen kuin työnkulkua jatketaan.

```php
Queuety::pause_workflow( $workflow_id );
```

### `Queuety::resume_workflow( $workflow_id )`

Jatka keskeytettyä työnkulkua.

```php
Queuety::resume_workflow( $workflow_id );
```

### `Queuety::cancel_workflow( $workflow_id )`

Peruuta työnkulku ja suorita kaikki rekisteröidyt siivouskäsittelijät. Asettaa tilaksi `cancelled` ja hautaa kaikki työnkulun odottavat ja käsittelyssä olevat työt.

```php
Queuety::cancel_workflow( $workflow_id );
```

Heittää `RuntimeException`-poikkeuksen, jos työnkulku on jo tilassa `completed` tai `cancelled`. Katso lisätiedot kohdasta [Peruutus](https://queuety.inline0.dev/fi/docs/workflows/cancellation).

### `Queuety::rewind_workflow( $workflow_id, $to_step )`

Palauta työnkulku aiempaan vaiheeseen ja suorita se uudelleen siitä eteenpäin. Tila palautetaan tapahtumalokin kohdasta `state_after` kyseiselle vaiheelle, ja seuraava vaihe asetetaan jonoon.

```php
Queuety::rewind_workflow( $workflow_id, to_step: 1 );
```

Heittää `RuntimeException`-poikkeuksen, jos kohdevaiheelle ei ole tallennettua tilaa. Edellyttää [Työnkulun tapahtumalokia](https://queuety.inline0.dev/fi/docs/workflows/event-log). Katso lisätiedot kohdasta [Aikamatkustus](https://queuety.inline0.dev/fi/docs/workflows/time-travel).

### `Queuety::fork_workflow( $workflow_id )`

Haarauta käynnissä oleva työnkulku itsenäiseksi kopioksi sen nykyisessä tilassa. Palauttaa uuden työnkulun tunnuksen.

```php
$forked_id = Queuety::fork_workflow( $workflow_id );
```

Haarautettu työnkulku saa oman tunnuksensa ja toimii alkuperäisestä riippumatta. Katso lisätiedot kohdasta [Haarauttaminen](https://queuety.inline0.dev/fi/docs/workflows/forking).

### `Queuety::export_workflow( $workflow_id )`

Vie työnkulun koko suoritushistoria JSON-sarjoitettavana taulukkona. Sisältää työnkulun rivin, kaikki työt, työnkulun tapahtumat ja lokimerkinnät.

```php
$data = Queuety::export_workflow( $workflow_id );
```

Katso kohdasta [Vienti ja toisto](https://queuety.inline0.dev/fi/docs/workflows/export-replay) lisätietoja rakenteesta JSON ja sen käyttötapauksista.

### `Queuety::replay_workflow( $data )`

Toista viety työnkulku nykyisessä ympäristössä. Luo vientitiedoista uuden työnkulun ja palauttaa sen tunnuksen.

```php
$new_id = Queuety::replay_workflow( $data );
```

Katso lisätiedot kohdasta [Vienti ja toisto](https://queuety.inline0.dev/fi/docs/workflows/export-replay).

### `Queuety::replace_wp_cron()`

Korvaa sisäänrakennettu WordPress cron -järjestelmä tuotteen Queuety ajastimella. Sieppaa tapahtumat `wp_schedule_event()`, `wp_unschedule_event()` ja `wp_get_scheduled_event()` ja reitittää toistuvat tapahtumat Queuety-työntekijän kautta.

```php
Queuety::replace_wp_cron();
```

Toimii vain, kun WordPress on ladattu. Katso lisätiedot kohdasta [WP-Cron-korvaus](https://queuety.inline0.dev/fi/docs/features/wp-cron).

### `Queuety::restore_wp_cron()`

Palauta WordPressn oletusarvoinen cron-toiminta poistamalla Queuety cron -siltakoukut.

```php
Queuety::restore_wp_cron();
```

Katso rajoitukset kohdasta [WP-Cron-korvaus](https://queuety.inline0.dev/fi/docs/features/wp-cron).

### `Queuety::signal( $workflow_id, $name, $data )`

Lähetä signaali työnkululle. Jos työnkulku odottaa parhaillaan tätä signaalia, se jatkuu heti. Muussa tapauksessa signaali tallennetaan ja käsitellään, kun työnkulku saavuttaa vastaavan `wait_for_signal`-vaiheen.

```php
Queuety::signal( $workflow_id, 'approved' );

// With data merged into workflow state
Queuety::signal( $workflow_id, 'approved', [
    'approved_by' => 'admin@example.com',
] );
```

Katso lisätiedot kohdasta [Työnkulun signaalit](https://queuety.inline0.dev/fi/docs/workflows/signals).

### `Queuety::approve_workflow( $workflow_id, $data = [], $signal_name = 'approval' )`

`signal()`-toiminnon semanttinen kääre hyväksyntävirtoja varten.

```php
Queuety::approve_workflow( $workflow_id, [
    'reviewer' => 'editor@example.com',
] );
```

### `Queuety::reject_workflow( $workflow_id, $data = [], $signal_name = 'rejected' )`

`signal()`-toiminnon semanttinen kääre hylkäysvirtoja varten.

```php
Queuety::reject_workflow( $workflow_id, [
    'reason' => 'needs citations',
] );
```

### `Queuety::submit_workflow_input( $workflow_id, $data = [], $signal_name = 'input' )`

`signal()`-toiminnon semanttinen kääre jäsenneltyä ihmisen antamaa syötettä varten.

```php
Queuety::submit_workflow_input( $workflow_id, [
    'notes' => 'Ship after legal review',
] );
```

### `Queuety::put_artifact( $workflow_id, $artifact_key, $content, $kind = 'json', $step_index = null, $metadata = [] )`

Tallenna yksi pysyvä artefakti työnkululle.

```php
Queuety::put_artifact(
    $workflow_id,
    'research_brief',
    [ 'summary' => 'done' ],
    'json',
    metadata: [ 'source' => 'agent' ],
);
```

### `Queuety::put_current_artifact( $artifact_key, $content, $kind = 'json', $metadata = [] )`

Tallenna yksi artefakti parhaillaan suoritettavalle työnkulun vaiheelle.

```php
Queuety::put_current_artifact(
    'draft',
    [ 'status' => 'ready' ],
    'json',
);
```

### `Queuety::workflow_artifact( $workflow_id, $artifact_key )`

Hae yksi tallennettu artefakti työnkululle.

```php
$artifact = Queuety::workflow_artifact( $workflow_id, 'draft' );
```

### `Queuety::workflow_artifacts( $workflow_id, $include_content = false )`

Listaa työnkulun artefaktit.

```php
$artifacts = Queuety::workflow_artifacts( $workflow_id );
```

### `Queuety::delete_workflow_artifact( $workflow_id, $artifact_key )`

Poista yksi työnkulun artefakti.

```php
Queuety::delete_workflow_artifact( $workflow_id, 'draft' );
```

## Tilakoneet

### `Queuety::machine( $name )`

Aloita tilakoneen rakentaminen. Palauttaa `StateMachineBuilder`-olion.

```php
use Queuety\Enums\StateMachineStatus;

$machine_id = Queuety::machine( 'agent_session' )
    ->state( 'awaiting_user' )
    ->on( 'user_message', 'planning' )
    ->state( 'planning' )
    ->action( PlanSessionAction::class )
    ->on( 'planned', 'completed' )
    ->state( 'completed', StateMachineStatus::Completed )
    ->dispatch( [ 'thread_id' => 42 ] );
```

### `StateMachineBuilder`-metodit

| Menetelmä | Kuvaus |
|---|---|
| `initial( string $state_name )` | Aseta alkutila eksplisiittisesti. |
| `state( string $state_name, ?StateMachineStatus $terminal_status = null )` | Aloita yhden tilan määrittäminen. |
| `action( string\|array $action_class )` | Rekisteröi jonoon lisättävä nykyisen tilan aloitustoiminto. Anna luokan nimi tai rakenteinen määrittely, jossa on `class`, `payload` ja `config`; `payload` välitetään `StateAction::handle()`-kohteeseen muodossa `$payload`. |
| `on( string $event, string $target, string\|array\|null $guard_class = null, ?string $name = null )` | Rekisteröi yksi tapahtumasiirtymä nykyisestä tilasta. Ehto hyväksyy saman rakenteisen muodon kuin `action()`. |
| `on_queue( string $queue )` | Aseta jono, jota käytetään jonoon lisättäville tilatoiminnoille. |
| `with_priority( Priority $priority )` | Aseta jonoon lisättävien tilatoimintojen prioriteetti. |
| `max_attempts( int $max_attempts )` | Aseta jonoon lisättävien tilatoimintojen uudelleenyritysten enimmäismäärä. |
| `version( string $version )` | Merkitse koneen määrittely sovellustason versiolla. |
| `idempotency_key( string $key )` | Tee lähetyksestä pysyvä kutsujan antamalla avaimella. Uudelleen lähettäminen samalla avaimella palauttaa alkuperäisen koneen tunnuksen. |
| `dispatch( array $initial_state = [] )` | Lähetä kone suoritettavaksi ja palauta koneen tunnus. |

Tilaan siirtymisen toimintaluokat voivat myös tarjota valinnaisen `config()`-metodin samoilla resurssikäytännön avaimilla, joita työnkulun vaiheet tukevat: `concurrency_group`, `concurrency_limit` ja `cost_units`.

### `Queuety::dispatch_state_machine_definition( $definition, $initial_state = [], $options = [] )`

Lähetä sarjoitettu tilakoneen määrittelypaketti suoritettavaksi. Useimmissa sovelluksissa kannattaa käyttää metodia `machine()->dispatch()`. Tämä alemman tason metodi on tarkoitettu sovittimille, jotka käynnistävät koneen ilman suoraa riippuvuutta rakentajasta.

```php
$machine_id = Queuety::dispatch_state_machine_definition(
    $definition,
    [ 'thread_id' => 42 ],
    [ 'idempotency_key' => 'thread:42' ],
);
```

### `Queuety::machine_status( $machine_id )`

Hae koneen nykyinen tila. Palauttaa `StateMachineState`-olion tai `null`.

```php
$status = Queuety::machine_status( $machine_id );

echo $status->name;               // 'agent_session'
echo $status->status->value;      // 'waiting_event'
echo $status->current_state;      // 'awaiting_review'
print_r( $status->state );        // public machine state
print_r( $status->available_events ); // valid incoming events in the current state
```

`StateMachineState` tarjoaa myös seuraavat ominaisuudet:

- `definition_version`
- `definition_hash`
- `idempotency_key`
- `error_message`
- `current_action`
- `terminal_status`

### `Queuety::machine_event( $machine_id, $event_name, $payload = [] )`

Lähetä yksi ulkoinen tapahtuma odottavalle koneelle.

```php
Queuety::machine_event(
    $machine_id,
    'approve',
    [
        'approved' => true,
        'reviewer' => 'editor@example.com',
    ]
);
```

Tietosisältö on siirtymien ehtojen käytettävissä, ja se yhdistetään julkiseen koneen tilaan, kun tapahtuma hyväksytään.

### `Queuety::list_machines( $limit = 50, $status = null )`

Luettele tallennetut konerivit tarkastelua varten.

```php
$machines = Queuety::list_machines();
$waiting  = Queuety::list_machines( status: 'waiting_event' );
```

Jokainen rivi sisältää koneen tunnuksen, nimen, tilan, nykyisen tilan, määrittelyn version, määrittelyn tiivisteen, idempotenssiavaimen sekä elinkaaren aikaleimat.

### `Queuety::machine_timeline( $machine_id, $limit = 100, $offset = 0 )`

Hae yhden koneen pysyvä tapahtumajana.

```php
$timeline = Queuety::machine_timeline( $machine_id );
$page_two = Queuety::machine_timeline( $machine_id, 100, 100 );
```

Kukin tapahtumarivi sisältää seuraavat: `id`, `machine_id`, `job_id`, `state_name`, `handler`, `event`, `event_name`, `transition_name`, `queue`, `attempt`, `input`, `output`, `state_before`, `state_after`, `context`, `artifacts`, `chunks`, `error`, `duration_ms` ja `created_at`.

### `Queuety::machine_trace( $machine_id )`

Hae normalisoitu jälkipaketti tilakoneen virheenjäljittimelle UI.

```php
$trace = Queuety::machine_trace( $machine_id );
```

Jälki sisältää `machine`, ryhmitellyt `states`, raakamuotoiset `events`, korreloidun toimintoa koskevan `jobs`-tiedon, `logs`, `artifacts` ja `chunks`.

### `Queuety::machine_state_at( $machine_id, $event_id )`

Hae julkinen tila tietyn koneen jälkitapahtuman jälkeen tai `null`, jos tapahtumaa ei löydy.

```php
$state = Queuety::machine_state_at( $machine_id, $event_id );
```

Katso [Tilakoneet](https://queuety.inline0.dev/fi/docs/state-machines), jossa kuvataan elinkaarimalli ja käyttötavat.

## Työnkulkumallit

### `Queuety::define_workflow( $name )`

Luo työnkulun rakentaja mallina käytettäväksi.

```php
$builder = Queuety::define_workflow( 'onboarding' )
    ->then( CreateAccountHandler::class )
    ->then( SendWelcomeEmailHandler::class );
```

### `Queuety::register_workflow_template( $builder )`

Rekisteröi työnkulkumalli.

```php
Queuety::register_workflow_template( $builder );
```

### `Queuety::run_workflow( $name, $payload, $options = [] )`

Lähetä rekisteröity työnkulkumalli suoritettavaksi nimen perusteella. Palauttaa työnkulun tunnuksen.

```php
$workflow_id = Queuety::run_workflow( 'onboarding', [ 'email' => 'user@example.com' ] );

$workflow_id = Queuety::run_workflow(
    'onboarding',
    [ 'email' => 'user@example.com' ],
    [ 'idempotency_key' => 'onboarding:user@example.com' ],
);
```

Heittää poikkeuksen `RuntimeException`, jos mallia ei ole rekisteröity.

### `Queuety::dispatch_workflow_definition( $definition, $payload, $options = [] )`

Lähetä työnkulku suoritettavaksi ajonaikaisesta määrittelypaketista.

Useimmissa sovelluksissa kannattaa käyttää metodia `run_workflow()` tai `workflow()->dispatch()`. Tämä alemman tason metodi mahdollistaa sen, että uudelleenkäytettävät sovittimet voivat lähettää sarjoitetun työnkulun määrittelyn suoritettavaksi ilman riippuvuutta sisäisistä työnkulunhallinnan metodeista.

```php
$workflow_id = Queuety::dispatch_workflow_definition(
    $definition,
    [ 'email' => 'user@example.com' ],
    [ 'idempotency_key' => 'onboarding:user@example.com' ],
);
```

### `Queuety::on_action( $hook, $workflow, $map = null, $when = null, $idempotency_key = null, $priority = 10, $accepted_args = null )`

Rekisteröi toiminto WordPress, joka lähettää työnkulun suoritettavaksi.

```php
Queuety::on_action(
    'save_post',
    workflow: 'content_review',
    map: static fn ( int $post_id, object $post, bool $update ): array => [
        'post_id' => $post_id,
        'post_type' => $post->post_type,
        'update' => $update,
    ],
    when: static fn ( int $post_id, object $post ): bool => 'post' === $post->post_type,
    idempotency_key: static fn ( int $post_id ): string => "save_post:{$post_id}",
);
```

`$workflow` voi olla jompikumpi seuraavista:

- rekisteröidyn työnkulkumallin nimi
- upotettu `WorkflowBuilder`

`map`, `when` ja `idempotency_key` suoritetaan synkronisesti nykyisen WordPress-pyynnön aikana. Vain työnkulun vaiheet suoritetaan asynkronisesti lähettämisen jälkeen.

Katso täydellinen opas kohdasta [Toimintojen käynnistimet](https://queuety.inline0.dev/fi/docs/features/action-triggers).

### `Queuety::workflow_templates()`

Hae työnkulkumallien rekisteri.

```php
$registry = Queuety::workflow_templates();
$template = $registry->get( 'onboarding' ); // WorkflowTemplate or null
```

### `Queuety::load_workflows( $directory, $recursive )`

Lataa ja rekisteröi kaikki työnkulkutiedostot hakemistosta. Jokaisen `.php`-tiedoston tulee palauttaa `WorkflowBuilder`. Palauttaa rekisteröityjen työnkulkujen määrän.

```php
$count = Queuety::load_workflows( __DIR__ . '/workflows/' );
$count = Queuety::load_workflows( __DIR__ . '/workflows/', recursive: true );
```

### `Queuety::load_workflow_file( $file_path )`

Lataa ja rekisteröi yksittäinen työnkulkutiedosto. Palauttaa `WorkflowTemplate`-arvon tai `null`-arvon, jos tiedosto ei palauta rakentajaa.

```php
$template = Queuety::load_workflow_file( __DIR__ . '/workflows/onboard-user.php' );
```

## Ajoitus

### `Queuety::schedule( $handler, $payload )`

Luo toistuva ajastus. Palauttaa `PendingSchedule`-rakentajan.

```php
Queuety::schedule( 'cleanup_handler' )
    ->every( '1 hour' )
    ->on_queue( 'maintenance' );

Queuety::schedule( 'nightly_report' )
    ->cron( '0 3 * * *' )
    ->on_queue( 'reports' );
```

### `PendingSchedule`-metodit

| Menetelmä | Kuvaus |
|---|---|
| `every( string $interval )` | Aseta aikavälilauseke (e.g, `1 hour`, `30 minutes`) |
| `cron( string $expression )` | Aseta 5-kenttäinen cron-lauseke |
| `overlap( OverlapPolicy $policy )` | Aseta päällekkäisyyksien käytäntö (oletus: `Allow`). Katso [Ajoitus](https://queuety.inline0.dev/fi/docs/features/scheduling). |
| `on_queue( string $queue )` | Aseta kohdejono (oletus: `default`) |
| `id()` | Pakota lähetys ja palauta ajastuksen tunnus |

### `Queuety::scheduler()`

Hae sisäinen `Scheduler`-instanssi.

```php
$scheduler = Queuety::scheduler();
$schedules = $scheduler->list();
$scheduler->remove( 'handler_name' );
$count = $scheduler->tick(); // manually trigger
```

## Käsittelijöiden rekisteröinti

### `Queuety::register( $name, $class )`

Rekisteröi käsittelijäluokka nimellä.

```php
Queuety::register( 'send_email', SendEmailHandler::class );
```

### `Queuety::discover_handlers( $directory, $namespace )`

Etsi ja rekisteröi käsittelijäluokat automaattisesti hakemistosta. Palauttaa rekisteröityjen käsittelijöiden määrän.

```php
$count = Queuety::discover_handlers( __DIR__ . '/handlers', 'MyPlugin\\Handlers' );
```

### `Queuety::registry()`

Hae käsittelijärekisteri.

```php
$registry = Queuety::registry();
```

## Havainnoitavuus

### `Queuety::logger()`

Hae `Logger`-instanssi lokimerkintöjen kyselyä varten.

```php
$logger = Queuety::logger();
$logs   = $logger->for_job( 42 );
$logs   = $logger->for_workflow( 7 );
$logs   = $logger->for_handler( 'send_email', 50 );
$logs   = $logger->for_event( LogEvent::Failed, 50 );
$logs   = $logger->since( new \DateTimeImmutable( '-1 hour' ), 100 );
$count  = $logger->purge( 30 );
```

### `Queuety::metrics()`

Hae `Metrics`-instanssi.

```php
$stats = Queuety::metrics()->handler_stats( 60 ); // last 60 minutes
```

### `Queuety::webhook_notifier()`

Hae `WebhookNotifier`-instanssi.

```php
$notifier = Queuety::webhook_notifier();
$id       = $notifier->register( 'job.buried', 'https://hooks.slack.com/...' );
$webhooks = $notifier->list();
$notifier->remove( $id );
```

### `Queuety::rate_limiter()`

Hae `RateLimiter`-instanssi.

```php
$limiter = Queuety::rate_limiter();
$limiter->register( 'call_openai', 60, 60 );
```

## Välimuisti

### `Queuety::cache()`

Hae aktiivinen välimuistin taustajärjestelmän instanssi.

```php
$cache = Queuety::cache();
$cache->set( 'my_key', 'my_value', 60 );
$value = $cache->get( 'my_key' );
```

### `Queuety::set_cache( $cache )`

Vaihda välimuistin taustajärjestelmää. Kutsu tätä ennen `Queuety::init()`-metodia, jos haluat käyttää omaa toteutusta.

```php
Queuety::set_cache( new RedisCache() );
Queuety::init( $connection );
```

### `QUEUETY_CACHE_TTL`

Välimuistin oletusarvoinen TTL sekunteina (oletus: `5`). Aseta tämä vakio tiedostossa `wp-config.php`, jos haluat muuttaa sisäisten välimuistitoimintojen oletusarvoista TTL-arvoa.

```php
define( 'QUEUETY_CACHE_TTL', 10 );
```

Katso kohdasta [Välimuisti](https://queuety.inline0.dev/fi/docs/features/caching) lisätietoja taustajärjestelmistä ja automaattisesta tunnistuksesta.

## Tilakoneen tapahtumaloki

### `Queuety::machine_events()`

Hae `StateMachineEventLog`-instanssi.

```php
$log = Queuety::machine_events();
```

## Työnkulun tapahtumaloki

### `Queuety::workflow_events()`

Hae `WorkflowEventLog`-instanssi.

```php
$log = Queuety::workflow_events();
```

### `Queuety::workflow_timeline( $workflow_id, $limit = 100, $offset = 0 )`

Hae työnkulun täydellinen tapahtumajana. Palauttaa tapahtumarivien taulukon tunnuksen mukaan järjestettynä.

```php
$events = Queuety::workflow_timeline( $workflow_id );
$next   = Queuety::workflow_timeline( $workflow_id, 100, 100 );
```

Kukin tapahtumarivi sisältää seuraavat: `id`, `workflow_id`, `job_id`, `parent_event_id`, `step_index`, `step_name`, `step_type`, `handler`, `event`, `queue`, `attempt`, `input`, `output`, `state_before`, `state_after`, `context`, `artifacts`, `chunks`, `error`, `error_message` (kopioitu kohteesta `error.message`), `duration_ms` ja `created_at`.

### `Queuety::workflow_trace( $workflow_id )`

Hae normalisoitu jälkipaketti työnkulun virheenjäljittimelle UI.

```php
$trace = Queuety::workflow_trace( $workflow_id );
```

Jälki sisältää `workflow`, ryhmitellyt `steps`, raakamuotoiset `events`, `jobs`, `logs`, `artifacts`, `chunks`, `signals` ja `wait_dependencies`.

### `Queuety::trace_input( $input )`

Aseta sovellustason syöte parhaillaan suoritettavalle työnkulun vaiheelle.

### `Queuety::trace_output( $output )`

Aseta sovellustason tuloste parhaillaan suoritettavalle työnkulun vaiheelle.

### `Queuety::trace_context( array $context )`

Yhdistä sovellustason konteksti parhaillaan suoritettavaan työnkulun vaiheeseen.

### `Queuety::workflow_state_at( $workflow_id, $step_index )`

Hae julkinen tila tietyn työnkulun vaiheen valmistumisen tai jatkamisen jälkeen tai `null`, jos vaihetta ei löydy.

```php
$state = Queuety::workflow_state_at( $workflow_id, 2 );
```

Katso kohdasta [Työnkulun tapahtumaloki](https://queuety.inline0.dev/fi/docs/workflows/event-log) käyttötapaukset ja CLI-komennot.

## Sisäiset instanssit

Nämä metodit palauttavat sisäisiä instansseja edistyneisiin käyttötapauksiin.

| Menetelmä | Palauttaa | Kuvaus |
|---|---|---|
| `Queuety::queue()` | `Queue` | Jonotoiminnot (varaa, vapauta, siirrä sivuun) |
| `Queuety::worker()` | `Worker` | Työntekijäprosessin hallinta |
| `Queuety::workflow_manager()` | `Workflow` | Työnkulun orkestrointi |
| `Queuety::machines()` | `StateMachine` | Tilakoneen elinkaaren hallinta |
| `Queuety::connection()` | `Connection` | Tietokantayhteys |
| `Queuety::batch_manager()` | `BatchManager` | Erien elinkaaren hallinta (peruuta, siisti) |
| `Queuety::chunk_store()` | `ChunkStore` | Osien tallennus suoratoistovaiheille |
| `Queuety::machine_events()` | `StateMachineEventLog` | Tilakoneen jälkitapahtumat ja normalisoidut jälkipaketit |
| `Queuety::workflow_events()` | `WorkflowEventLog` | Työnkulun jälkitapahtumat ja normalisoidut jälkipaketit |
| `Queuety::resource_manager()` | `ResourceManager` | Työntekijöiden pääsyprofiilit, painotetut budjetit ja järjestelmämuistin tarkastelu |
| `Queuety::cache()` | `Cache` | Välimuistin taustajärjestelmän instanssi |

## Testaus

### `Queuety::fake()`

Korvaa jono muistissa olevalla testitoteutuksella. Palauttaa `QueueFake`-instanssin, joka tallentaa lähetetyt työt koskematta tietokantaan. `create_batch()` tallentaa myös erien testimetatiedot; ketjuja tarkastellaan niiden yksittäisten lähetettyjen töiden perusteella.

```php
$fake = Queuety::fake();
SendEmailJob::dispatch( 'user@example.com', 'Hello', 'Hi!' );
$fake->assert_pushed( SendEmailJob::class );
```

### `Queuety::reset()`

Nollaa kaikki sisäinen tila, myös jonon testitoteutus. Kutsu kohdassa `tearDown()`.

```php
Queuety::reset();
```

### `QueueFake`-metodit

| Menetelmä | Kuvaus |
|---|---|
| `assert_pushed( string $class, ?Closure $callback )` | Varmista, että työluokka lisättiin jonoon. Valinnainen takaisinkutsu suodattaa työn tietojen perusteella. |
| `assert_pushed_times( string $class, int $count )` | Varmista, että työ lisättiin jonoon täsmälleen N kertaa. |
| `assert_not_pushed( string $class )` | Varmista, ettei työtä lisätty koskaan jonoon. |
| `assert_nothing_pushed()` | Varmista, ettei yhtäkään työtä lisätty jonoon. |
| `assert_batched( ?Closure $callback )` | Varmista, että erä lähetettiin. Valinnainen takaisinkutsu suodattaa erän tietojen perusteella. |
| `pushed( string $class )` | Hae kaikki luokan tallennetut lähetykset. Palauttaa taulukon. |
| `batches()` | Hae kaikki tallennetut erät. Palauttaa taulukon. |
| `reset()` | Tyhjennä kaikki tallennetut työt ja erät. |

Katso täydelliset esimerkit kohdasta [Testaus](https://queuety.inline0.dev/fi/docs/features/testing).

## Rajapinnat

### `Handler`

Rajapinta yksinkertaisille työn käsittelijöille.

```php
interface Handler {
    public function handle( array $payload ): void;
    public function config(): array;
}
```

`config()` voi palauttaa arvon `queue`, `max_attempts`, `backoff`, `rate_limit`, `concurrency_group`, `concurrency_limit` ja `cost_units`.

### `Step`

Rajapinta työnkulun vaiheen käsittelijöille.

```php
interface Step {
    public function handle( array $state ): array;
    public function config(): array;
}
```

`config()` voi palauttaa arvon `max_attempts`, `backoff`, `concurrency_group`, `concurrency_limit` ja `cost_units`.

### `Contracts\ForEachHandler`

Rajapinta dynaamisten jokaisen alkion haarojen käsittelijöille.

```php
namespace Queuety\Contracts;

interface ForEachHandler {
    public function handle_item( array $state, mixed $item, int $index ): array;
    public function config(): array;
}
```

`config()` voi palauttaa arvon `max_attempts`, `backoff`, `rate_limit`, `concurrency_group`, `concurrency_limit` ja `cost_units`.

### `Contracts\ForEachReducer`

Valinnainen tulosten kokoaja jokaisen alkion käsittelyn tuloksille.

```php
namespace Queuety\Contracts;

interface ForEachReducer {
    public function reduce( array $state, array $for_each ): array;
}
```

### `Contracts\Compensation`

Rajapinta vaiheen kumoamisen käsittelijöille.

```php
namespace Queuety\Contracts;

interface Compensation {
    public function handle( array $state ): void;
}
```

### `Contracts\RepeatCondition`

Rajapinta silmukoiden ehdoille, joita `repeat_until()` ja `repeat_while()` käyttävät, kun avainarvojen vertailu ei riitä.

```php
namespace Queuety\Contracts;

interface RepeatCondition {
    public function matches( array $state ): bool;
}
```

### `Contracts\StateAction`

Rajapinta jonoon lisättäville tilan aloitustoiminnoille.

```php
namespace Queuety\Contracts;

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

`$payload` saa toimintomäärittelystä rakenteisen `payload`-arvon, jos kone on määritelty sellaisen kanssa. Palauta julkisen tilan päivitykset. Sisällytä `_event` ja halutessasi `_event_payload`, kun toiminnon pitää käynnistää siirtymä heti.

Tilatoiminnot voivat myös määritellä valinnaisen `config()`-metodin. Queuety lukee siitä arvot `concurrency_group`, `concurrency_limit` ja `cost_units`, kun aloitustoiminto lisätään jonoon.

### `Contracts\StateGuard`

Rajapinta tilakoneen siirtymien ehdoille.

```php
namespace Queuety\Contracts;

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

### `Contracts\Job`

Rajapinta itsenäisille, lähetettäville työluokille. Työluokat sisältävät tietosisältönsä julkisina ominaisuuksina ja suorituslogiikkansa kohteessa `handle()`.

```php
namespace Queuety\Contracts;

interface Job {
    public function handle(): void;
}
```

Työluokat voivat määritellä valinnaisen `middleware()`-metodin, joka palauttaa taulukon `Contracts\Middleware`-instansseja.

### `Contracts\Cache`

Rajapinta välimuistin taustajärjestelmille. Katso kohdasta [Välimuisti](https://queuety.inline0.dev/fi/docs/features/caching) sisäänrakennetut toteutukset ja omat taustajärjestelmät.

```php
namespace Queuety\Contracts;

interface Cache {
    public function get( string $key ): mixed;
    public function set( string $key, mixed $value, int $ttl = 0 ): void;
    public function delete( string $key ): void;
    public function has( string $key ): bool;
    public function add( string $key, mixed $value, int $ttl = 0 ): bool;
    public function flush(): void;
}
```

| Menetelmä | Palauttaa | Kuvaus |
|---|---|---|
| `get( $key )` | `mixed` | Hae arvo. Palauttaa arvon `null`, jos sitä ei löydy tai se on vanhentunut. |
| `set( $key, $value, $ttl )` | `void` | Tallenna arvo. TTL 0 tarkoittaa, ettei arvo vanhene. |
| `delete( $key )` | `void` | Poista arvo. |
| `has( $key )` | `bool` | Tarkista, onko avain olemassa eikä ole vanhentunut. |
| `add( $key, $value, $ttl )` | `bool` | Atominen asetus vain, jos avainta ei ole. Palauttaa arvon `true`, jos arvo asetettiin. |
| `flush()` | `void` | Poista kaikki kohteet välimuistista. |

### `WorkflowEventLog`

Tallentaa työnkulun vaiheiden siirtymät täydellisine jälkikonteksteineen. Käytettävissä kohteen `Queuety::workflow_events()` kautta.

| Menetelmä | Palauttaa | Kuvaus |
|---|---|---|
| `record_event( array $event )` | `void` | Tallenna raakamuotoinen jälkitapahtuma |
| `record_step_started( ... )` | `void` | Tallenna step_started-tapahtuma, jossa on syöte ja tila ennen suoritusta |
| `record_step_completed( ... )` | `void` | Tallenna step_completed-tapahtuma, jossa on syöte, tuloste sekä tila ennen suoritusta ja sen jälkeen |
| `record_step_failed( ... )` | `void` | Tallenna step_failed-tapahtuma, jossa on jälkikonteksti ja rakenteiset virhetiedot |
| `get_timeline( int $workflow_id, ?int $limit = 100, int $offset = 0 )` | `array` | Hae työnkulun jälkitapahtumat järjestyksessä ja halutessasi sivutettuina |
| `get_trace( int $workflow_id )` | `array` | Hae normalisoitu jälkipaketti |
| `get_state_at_step( int $workflow_id, int $step_index )` | `array\|null` | Hae julkinen tila tietyn vaiheen valmistumisen tai jatkamisen jälkeen |
| `prune( int $older_than_days )` | `int` | Poista tapahtumat, jotka ovat annettua päivämäärää vanhempia. Palauttaa poistettujen rivien määrän. |

### `StateMachineEventLog`

Tallentaa tilakoneen elinkaari-, toiminto-, siirtymä- ja ehtotapahtumat käyttäen samoja jälkikenttiä kuin työnkulkutapahtumissa.

| Menetelmä | Palauttaa | Kuvaus |
|---|---|---|
| `record_event( array $event )` | `void` | Tallenna raakamuotoinen koneen jälkitapahtuma |
| `get_timeline( int $machine_id, ?int $limit = 100, int $offset = 0 )` | `array` | Hae koneen jälkitapahtumat järjestyksessä ja halutessasi sivutettuina |
| `get_trace( int $machine_id )` | `array` | Hae normalisoitu koneen jälkipaketti |
| `get_state_at_event( int $machine_id, int $event_id )` | `array\|null` | Hae julkinen tila tietyn koneen jälkitapahtuman jälkeen |
| `prune( int $older_than_days )` | `int` | Poista tapahtumat, jotka ovat annettua päivämäärää vanhempia. Palauttaa poistettujen rivien määrän. |

### `Contracts\StreamingStep`

Rajapinta työnkulun vaiheiden käsittelijöille, jotka tuottavat osista koostuvan virran. Jokainen tuotettu arvo tallennetaan heti tietokantaan. Katso [Suoratoistovaiheet](https://queuety.inline0.dev/fi/docs/workflows/streaming).

```php
namespace Queuety\Contracts;

interface StreamingStep {
    public function stream( array $state, array $existing_chunks = [] ): \Generator;
    public function on_complete( array $chunks, array $state ): array;
    public function config(): array;
}
```

| Menetelmä | Kuvaus |
|---|---|
| `stream( $state, $existing_chunks )` | Generaattori, joka tuottaa merkkijono-osia. Jokainen tuotto käynnistää välittömän tietokantakirjoituksen. Uudelleenyrityksen yhteydessä `$existing_chunks` sisältää aiemmin tallennetut osat. |
| `on_complete( $chunks, $state )` | Kutsutaan virran päätyttyä. Palauttaa tiedot, jotka yhdistetään työnkulun tilaan. |
| `config()` | Valinnainen määritys. Tukee arvoja `max_attempts`, `backoff`, `concurrency_group`, `concurrency_limit` ja `cost_units`. |

### `ChunkStore`

Hallinnoi osien tallennusta suoratoistovaiheita varten. Käytettävissä kohteen `Queuety::chunk_store()` kautta.

| Menetelmä | Palauttaa | Kuvaus |
|---|---|---|
| `get_chunks( int $job_id )` | `string[]` | Hae kaikki työn osat osan indeksin mukaan järjestettyinä |
| `append_chunk( int $job_id, int $chunk_index, string $content, ?int $workflow_id, ?int $step_index )` | `void` | Lisää yksi osa |
| `clear_chunks( int $job_id )` | `void` | Poista kaikki työn osat |
| `chunk_count( int $job_id )` | `int` | Laske työn osien määrä |
| `get_accumulated( int $job_id )` | `string` | Yhdistä kaikki osat yhdeksi merkkijonoksi |

### `Heartbeat`

Staattinen apuohjelma toimintasykkeiden lähettämiseen vaiheen käsittelijöiden ja suoratoistovaiheiden sisältä. Katso [Toimintasykkeet](https://queuety.inline0.dev/fi/docs/features/heartbeats).

| Menetelmä | Kuvaus |
|---|---|
| `Heartbeat::init( int $job_id, Connection $conn )` | Aseta työn konteksti. Työntekijä kutsuu automaattisesti. |
| `Heartbeat::beat( array $progress = [] )` | Lähetä toimintasyke. Päivittää arvon `reserved_at` ja halutessasi tallentaa edistymistiedot kohteeseen `heartbeat_data`. |
| `Heartbeat::clear()` | Tyhjennä työn konteksti. Työntekijä kutsuu automaattisesti. |
| `Heartbeat::current_job_id()` | Hae nykyisen työn tunnus (testausta varten). |

### `Contracts\Middleware`

Rajapinta työn väliohjelmistoille. Väliohjelmisto kietoo työn suorituksen sipulimalliseen käsittelyputkeen.

```php
namespace Queuety\Contracts;

interface Middleware {
    public function handle( object $job, \Closure $next ): void;
}
```

## Piirteet

### `Dispatchable`

Tarjoaa staattiset lähetysmetodit rajapinnan `Contracts\Job` toteuttaville työluokille. Rakentajan argumentit välitetään eteenpäin työinstanssin luomiseksi.

```php
use Queuety\Contracts\Job;
use Queuety\Dispatchable;

class SendEmailJob implements Job {
    use Dispatchable;
    // ...
}

// Dispatches a new SendEmailJob instance
SendEmailJob::dispatch( 'user@example.com', 'Subject', 'Body' );
```

| Menetelmä | Palauttaa | Kuvaus |
|---|---|---|
| `dispatch( ...$args )` | `PendingJob` | Luo instanssi ja lähetä se suoritettavaksi |
| `dispatch_if( bool $condition, ...$args )` | `PendingJob\|null` | Lähetä vain, jos `$condition` on tosi |
| `dispatch_unless( bool $condition, ...$args )` | `PendingJob\|null` | Lähetä vain, jos `$condition` on epätosi |
| `with_chain( array $jobs )` | `ChainBuilder` | Aloita ketju tästä työluokasta |

```php
// Conditional dispatch
SendEmailJob::dispatch_if( $user->wants_email, $user->email, 'Hello', 'Hi!' );
SendEmailJob::dispatch_unless( $maintenance_mode, $user->email, 'Hello', 'Hi!' );

// Chain from a job class
FetchDataJob::with_chain( [
    new ProcessDataJob(),
    new NotifyCompleteJob(),
] )->dispatch();
```

### Työn ominaisuudet

Työluokat voivat määritellä julkisia ominaisuuksia, joita työntekijä lukee reflektion avulla ohittaakseen uudelleenyritys- ja aikakatkaisukäytännöt.

| Ominaisuus | Tyyppi | Kuvaus |
|---|---|---|
| `$tries` | `int` | Yritysten enimmäismäärä ennen kuin työ siirretään sivuun |
| `$timeout` | `int` | Suorituksen enimmäisaika sekunteina (edellyttää kohdetta `pcntl`) |
| `$backoff` | `array` | Kasvavat viivearvot sekunteina kullekin uudelleenyritykselle |

```php
class ImportProductsJob implements Job {
    use Dispatchable;

    public int $tries = 5;
    public int $timeout = 120;
    public array $backoff = [ 10, 30, 60, 120 ];

    // ...
}
```

### `failed()`-koukku

Kun työ siirretään sivuun kaikkien uudelleenyritysten jälkeen, työntekijä kutsuu työinstanssin `failed()`-metodia, jos sellainen on määritelty.

```php
public function failed( \Throwable $exception ): void {
    error_log( "Job failed: {$exception->getMessage()}" );
}
```

## Sisäänrakennetut väliohjelmistot

Kaikki väliohjelmistoluokat toteuttavat rajapinnan `Contracts\Middleware`, ja ne sijaitsevat nimitilassa `Queuety\Middleware`.

| Luokka | Kuvaus |
|---|---|
| `RateLimited( int $max, int $window )` | Rajoita suoritusten määrä arvoon `$max` `$window` sekunnin aikana |
| `Timeout( int $seconds )` | Lopeta työ `$seconds` sekunnin kuluttua (vaatii `pcntl`) |
| `UniqueJob( ?string $key )` | Estä samanaikainen suoritus tietokantalukolla |
| `WithoutOverlapping( string $key, int $release_after )` | Estä päällekkäiset suoritukset lukon automaattisella vanhenemisella |
| `ThrottlesExceptions( int $max_attempts, int $decay_minutes )` | Rajoita poikkeuksia, jotta ulkoisen palvelun käyttökatko ei aiheuta työryöppyjä |

Katso [Middleware](https://queuety.inline0.dev/fi/docs/features/middleware) käyttöohjeet ja esimerkit.

## Enumeraatiot

### `Priority`

```php
enum Priority: int {
    case Low    = 0;
    case Normal = 1;
    case High   = 2;
    case Urgent = 3;
}
```

### `JobStatus`

```php
enum JobStatus: string {
    case Pending    = 'pending';
    case Processing = 'processing';
    case Completed  = 'completed';
    case Failed     = 'failed';
    case Buried     = 'buried';
}
```

### `WorkflowStatus`

```php
enum WorkflowStatus: string {
    case Running        = 'running';
    case Completed      = 'completed';
    case Failed         = 'failed';
    case Paused         = 'paused';
    case WaitingForSignal  = 'waiting_for_signal';
    case WaitingForWorkflows = 'waiting_for_workflows';
    case Cancelled      = 'cancelled';
}
```

### `StateMachineStatus`

```php
enum StateMachineStatus: string {
    case Running = 'running';
    case WaitingEvent = 'waiting_event';
    case Completed = 'completed';
    case Failed = 'failed';
    case Paused = 'paused';
    case Cancelled = 'cancelled';
}
```

### `BackoffStrategy`

```php
enum BackoffStrategy: string {
    case Fixed       = 'fixed';
    case Linear      = 'linear';
    case Exponential = 'exponential';
}
```

### `ForEachMode`

```php
enum ForEachMode: string {
    case All = 'all';
    case FirstSuccess = 'first_success';
    case Quorum = 'quorum';
}
```

### `WaitMode`

```php
enum WaitMode: string {
    case All    = 'all';
    case Any    = 'any';
    case Quorum = 'quorum';
}
```

### `LogEvent`

```php
enum LogEvent: string {
    case Started                  = 'started';
    case Completed                = 'completed';
    case Failed                   = 'failed';
    case Buried                   = 'buried';
    case Retried                  = 'retried';
    case WorkflowStarted          = 'workflow_started';
    case WorkflowCompleted        = 'workflow_completed';
    case WorkflowFailed           = 'workflow_failed';
    case WorkflowPaused           = 'workflow_paused';
    case WorkflowResumed          = 'workflow_resumed';
    case WorkflowCancelled        = 'workflow_cancelled';
    case WorkflowRewound          = 'workflow_rewound';
    case WorkflowForked           = 'workflow_forked';
    case WorkflowDeadlineExceeded = 'workflow_deadline_exceeded';
    case Debug                    = 'debug';
}
```

### `OverlapPolicy`

```php
enum OverlapPolicy: string {
    case Allow  = 'allow';
    case Skip   = 'skip';
    case Buffer = 'buffer';
}
```

Katso [Scheduling](https://queuety.inline0.dev/fi/docs/features/scheduling), miten kukin käytäntö toimii.

## Attribuutit

### `#[QueuetyHandler]`

PHP 8 -attribuutti automaattista rekisteröintiä varten. Katso [PHP Attributes](https://queuety.inline0.dev/fi/docs/features/attributes).

```php
use Queuety\Attributes\QueuetyHandler;

#[QueuetyHandler( name: 'send_email', queue: 'emails', max_attempts: 5 )]
class SendEmailHandler implements Handler {
    // ...
}
```

## CLI-silta

### `Queuety::cli_command()`

Palauttaa julkaistun WP-CLI-juurikomennon nimen.

Juurikomento on oletusarvoisesti `queuety`. Määritä `QUEUETY_CLI_COMMAND` ennen kuin Queuety käynnistyy, jos komento pitää julkaista eri nimellä.

### `Queuety::cli_command_map()`

Palauttaa sarjoitettavan Queuety CLI-luettelon sellaisille testikehyksille, joiden on tunnettava toimitettujen komentojen rajapinta ilman WP-CLI-luokkien läpikäyntiä.

Kukin merkintä sisältää:
- pysyvän toiminnon tunnisteen
- suhteellisen CLI-polun
- WP-CLI-käsittelijäluokan ja metodin
- mahdolliset suoritusympäristöt
- sovittimen, joka muuntaa raakamuotoiset CLI-argumentit suoritussuunnitelmaksi

### `Queuety::resolve_cli_command( $path, $args, $assoc_args )`

Muuntaa jäsennetyn CLI-kutsun suoritussuunnitelmaksi, jonka testikehyksen tulee suorittaa.

```php
$plan = Queuety::resolve_cli_command(
    [ 'workflow', 'export' ],
    [ '42' ],
    [ 'output' => '/tmp/workflow.json' ]
);

echo $plan['callable']; // Queuety\Queuety::export_workflow_to_file
print_r( $plan['arguments'] );
```

Suoritussuunnitelmat huomioivat tarkoituksella siirtotavan:
- komennot vastaavat julkisia PHP-kutsuttavia, joilla on normalisoidut argumentit
- luettelo sisältää kaikki mahdolliset suoritusympäristöt etukäteen, kun taas `callable` ja `transport` ilmaisevat jäsennetyn syötteen perusteella valitun haaran

Tämä on vakiomalli, jota Queuety käyttää agenttien testikehyksissä: pysyvä toiminnon tunniste, julkinen API-kohde ja sovittimen hallitsema normalisointi CLI-kohtaisille asioille, kuten jonojen oletusarvoille, JSON-hyötykuorman dekoodaukselle, työprosessijoukon haarautumiselle ja työnkulun vientitiedostojen käsittelylle.
