
# Roki potekov dela

Potekom dela lahko določite rok. Če se izvajajoči potek dela ne zaključi v določenem času, ga Queuety označi kot neuspešnega in po želji pokliče obravnavalnik. Poteki dela, ki so začasno ustavljeni ali čakajo na signal oziroma druge poteke dela, med čakanjem ne potečejo. Roke približno enkrat na minuto preverja dolgotrajno delujoč proces `wp queuety work`, ne pa delavci `--once` ali nadomestni mehanizem WP-Cron. To deluje kot stikalo za dolgotrajne poteke dela, ki ne smejo teči v nedogled.

## Nastavitev roka

Z metodo `must_complete_within()` gradnika poteka dela določite najdaljše dovoljeno trajanje. Z metodo `on_deadline()` registrirate obravnavalnik, ki se zažene, ko je rok prekoračen.

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

Metoda `must_complete_within()` sprejema poimenovane parametre, ki se seštejejo:

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

## Obravnavalnik roka

Razred obravnavalnika roka `on_deadline()` mora implementirati metodo `handle( array $state ): void`. Ta prejme javno stanje poteka dela (vse ključe, ki se ne začnejo z `_`).

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

Obravnavalnik roka ni obvezen. Če želite, da potek dela samo spodleti brez izvajanja lastne logike, uporabite `must_complete_within()` brez `on_deadline()`.

## Kako deluje preverjanje rokov

Delavec med obdelovalno zanko vsakih 60 sekund preveri pretečene roke. Ko najde potek dela, pri katerem je `status` še vedno `running`, `deadline_at` pa je v preteklosti, pokliče registrirani obravnavalnik `on_deadline`, potek dela označi kot neuspešen s sporočilom o napaki `Deadline exceeded` in zabeleži dogodek dnevnika `workflow_deadline_exceeded`. Rok je v vrstici poteka dela shranjen kot časovni žig `deadline_at` in izračunan ob razpošiljanju na podlagi nastavljene dolžine trajanja.

## Kaj se zgodi ob poteku roka

Ko potek dela preseže svoj rok, se njegovo stanje spremeni v `failed`, sporočilo o napaki se nastavi na `Deadline exceeded`, registrirani obravnavalnik roka se izvede sinhrono, zabeleži pa se tudi vnos dnevnika `workflow_deadline_exceeded`. Izvajajoča se opravila niso prekinjena sredi izvajanja, vendar potek dela ne bo napredoval prek meje koraka, pri katerem je rok potekel. Če obravnavalnik roka sproži izjemo, se ta tiho prestreže, potek dela pa je kljub temu označen kot neuspešen.

## Metode WorkflowBuilder

| Metoda | Opis |
|---|---|
| `must_complete_within( int $seconds = 0, int $minutes = 0, int $hours = 0, int $days = 0 )` | Nastavi najdaljše dovoljeno trajanje. Vsi parametri se seštejejo. |
| `on_deadline( string $handler_class )` | Registrira obravnavalnik, ki se pokliče, ko je rok prekoračen. |

## Primer: rok s ponovnim poskusom

Ponovni poskus poteka dela, ki mu je potekel rok, je le redko koristen. `retry_workflow()` ga ponastavi na `running` in ponovno postavi neuspešni korak v čakalno vrsto, vendar ne izbriše ali podaljša roka, zato ga bo naslednje preverjanje roka v približno minuti znova označilo kot neuspešnega. Namesto tega razpošljite nov potek dela.

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

## Rok in zakasnitve spanja

Roki veljajo za celotno trajanje poteka dela. Zakasnitve spanja (`->delay()`) začasno ustavijo potek dela za določen čas kot del zaporedja njegovih korakov. Potek dela z enourno zakasnitvijo spanja in dvournim rokom bo neuspešen, če koraki, ki niso spanje, skupaj trajajo več kot eno uro.
