
# Työnkulun määräajat

Työnkululle voi asettaa määräajan. Jos käynnissä oleva työnkulku ei valmistu määritetyssä ajassa, Queuety merkitsee sen epäonnistuneeksi ja kutsuu haluttaessa käsittelijää. Työnkulun määräaika ei umpeudu, kun se on tauolla tai odottaa signaalia tai muita työnkulkuja. Määräajat tarkistetaan noin kerran minuutissa pitkäkestoisessa `wp queuety work`-prosessissa, eivät `--once`-työntekijöissä tai WP-Cron-varajärjestelmässä. Tämä toimii kuolleen miehen kytkimenä pitkäkestoisille työnkuluille, joiden ei pidä jatkua loputtomiin.

## Määräajan asettaminen

Aseta suurin sallittu kesto työnkulun muodostajassa toiminnolla `must_complete_within()`. Rekisteröi toiminnolla `on_deadline()` käsittelijä, joka suoritetaan määräajan ylittyessä.

```php
use Queuety\Queuety;

Queuety::workflow( 'data_import' )
    ->then( FetchDataHandler::class )
    ->then( TransformDataHandler::class )
    ->then( LoadDataHandler::class )
    ->must_complete_within( hours: 24 )
    ->on_deadline( ImportTimeoutHandler::class )
    ->dispatch( [ 'source' => $url ] );
```

`must_complete_within()`-menetelmä hyväksyy nimettyjä parametreja, joiden arvot lasketaan yhteen:

```php
->must_complete_within( hours: 2, minutes: 30 )  // 2.5 hours
->must_complete_within( days: 1 )                 // 24 hours
->must_complete_within( seconds: 3600 )           // 1 hour
->must_complete_within( days: 1, hours: 12 )      // 36 hours
```

## Määräajan käsittelijä

`on_deadline()`-käsittelijäluokan on toteutettava `handle( array $state ): void`-menetelmä. Se saa julkisen työnkulun tilan (kaikki avaimet, jotka eivät ala merkillä `_`).

```php
class ImportTimeoutHandler {

    public function handle( array $state ): void {
        // Alert the team.
        wp_mail(
            'ops@example.com',
            'Import workflow timed out',
            'Workflow for source ' . ( $state['source'] ?? 'unknown' ) . ' exceeded its deadline.'
        );

        // Clean up partial work.
        if ( isset( $state['temp_file'] ) ) {
            unlink( $state['temp_file'] );
        }
    }
}
```

Määräajan käsittelijä on valinnainen. Jos haluat vain merkitä työnkulun epäonnistuneeksi suorittamatta omaa logiikkaa, käytä `must_complete_within()`-toimintoa ilman `on_deadline()`-käsittelijää.

## Määräaikojen tarkistuksen toiminta

Työntekijä tarkistaa umpeutuneet määräajat 60 sekunnin välein osana käsittelysilmukkaansa. Kun se löytää työnkulun, jonka `status` on yhä `running` ja jonka `deadline_at` on menneisyydessä, se kutsuu rekisteröityä `on_deadline`-käsittelijää, merkitsee työnkulun epäonnistuneeksi virheilmoituksella `Deadline exceeded` ja tallentaa `workflow_deadline_exceeded`-lokitapahtuman. Määräaika tallennetaan työnkulun riville muodossa `deadline_at`-aikaleima, ja se lasketaan käynnistyshetkellä määritetyn keston perusteella.

## Mitä määräajan umpeutuessa tapahtuu

Kun työnkulku ylittää määräaikansa, sen tilaksi asetetaan `failed`, virheilmoitukseksi asetetaan `Deadline exceeded`, määräajan käsittelijä suoritetaan synkronisesti, jos sellainen on rekisteröity, ja lokiin kirjataan merkintä `workflow_deadline_exceeded`. Käynnissä olevia töitä ei keskeytetä kesken suorituksen, mutta työnkulku ei etene vanhentuneen vaiheen rajan yli. Jos määräajan käsittelijä itse heittää poikkeuksen, poikkeus otetaan hiljaisesti kiinni ja työnkulun tilaksi jää silti epäonnistunut.

## WorkflowBuilderin metodit

| Metodi | Kuvaus |
|---|---|
| `must_complete_within( int $seconds = 0, int $minutes = 0, int $hours = 0, int $days = 0 )` | Aseta sallittu enimmäiskesto. Kaikki parametrit lasketaan yhteen. |
| `on_deadline( string $handler_class )` | Rekisteröi käsittelijä, jota kutsutaan määräajan ylittyessä. |

## Esimerkki: määräaika ja uudelleenyritys

Määräajan vuoksi epäonnistuneen työnkulun uudelleenyritys on harvoin hyödyllistä. `retry_workflow()` palauttaa sen tilaan `running` ja lisää epäonnistuneen vaiheen uudelleen jonoon, mutta se ei tyhjennä eikä pidennä määräaikaa, joten seuraava määräaikatarkistus epäonnistuu uudelleen noin minuutin kuluessa. Käynnistä sen sijaan uusi työnkulku.

```php
$status = Queuety::workflow_status( $workflow_id );

if ( 'failed' === $status->status->value ) {
    // Check if it was a deadline failure.
    // You may want to dispatch a new workflow instead of retrying.
    Queuety::retry_workflow( $workflow_id );
}
```

## Määräaika ja viiveet

Määräajat koskevat koko työnkulun kestoa. Viiveet (`->delay()`) keskeyttävät työnkulun kiinteäksi ajaksi osana sen vaiheiden sarjaa. Työnkulku, jossa on 1 tunnin viive ja 2 tunnin määräaika, epäonnistuu, jos muut kuin viivevaiheet kestävät yhteensä yli 1 tunnin.
