
# Ajoitus

Queuety tukee toistuvia töitä sisäänrakennetusti. `wp_cron`-ratkaisun sijaan aikataulut tallennetaan tietokantaan, ja pitkäkestoinen `wp queuety work`-prosessi (tai työntekijäpoolin pääprosessi) arvioi ne noin kerran minuutissa. `wp queuety work --once`, `wp queuety flush` ja lisäosan sisäänrakennettu WP-Cron-vararatkaisu eivät arvioi aikatauluja ([#14](https://github.com/inline0/queuety/issues/14)); jos pitkäkestoista työntekijää ei ole käynnissä, suorita `wp queuety schedule run` itse.

## Aikaväliin perustuva ajoitus

Käytä `every()`-toimintoa yksinkertaisiin aikaväliin perustuviin aikatauluihin. Lauseke voi olla mikä tahansa PHP-ratkaisun `DateTimeImmutable::modify()`-muodon kanssa yhteensopiva merkkijono:

```php
use Queuety\Queuety;

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

Queuety::schedule( 'sync_inventory' )
    ->every( '30 minutes' )
    ->on_queue( 'sync' );

Queuety::schedule( 'daily_report', [ 'type' => 'summary' ] )
    ->every( '1 day' );
```

## Cron-ajoitus

Käytä `cron()`-toimintoa tavallisiin 5-kenttäisiin cron-lausekkeisiin:

```php
// Every day at 3am
Queuety::schedule( 'nightly_cleanup' )
    ->cron( '0 3 * * *' );

// Every Monday at 9am
Queuety::schedule( 'weekly_digest' )
    ->cron( '0 9 * * 1' )
    ->on_queue( 'emails' );

// Every 15 minutes
Queuety::schedule( 'health_check' )
    ->cron( '*/15 * * * *' );
```

## Aikataulun asetukset

`PendingSchedule`-rakentaja tukee seuraavia metodeja:

| Metodi | Kuvaus |
|---|---|
| `every( string $interval )` | Aseta aikavälilauseke |
| `cron( string $expression )` | Aseta cron-lauseke |
| `on_queue( string $queue )` | Aseta kohdejono (oletus: `'default'`) |
| `overlap( OverlapPolicy $policy )` | Aseta päällekkäisyyden käsittelytapa (oletus: `Allow`) |

Sinun on kutsuttava joko `every()` tai `cron()` ennen aikataulun lähettämistä. Jos kumpaakaan ei aseteta, heitetään `RuntimeException`.

## Päällekkäisyyden käsittelytavat

Kun ajoitettu työ on yhä käynnissä (odottavana tai käsittelyssä) seuraavan ajastinhetken koittaessa, päällekkäisyyden käsittelytapa määrittää, mitä tapahtuu. Aseta se metodilla `overlap()`:

```php
use Queuety\Queuety;
use Queuety\Enums\OverlapPolicy;

Queuety::schedule( 'sync_inventory' )
    ->every( '5 minutes' )
    ->overlap( OverlapPolicy::Skip )
    ->on_queue( 'sync' );
```

`OverlapPolicy`-enumissa on kolme vaihtoehtoa:

| Käytäntö | Arvo | Toiminta |
|---|---|---|
| `OverlapPolicy::Allow` | `allow` | Lähetä aina uusi työ, vaikka edellinen suoritus olisi yhä käynnissä. Tämä on oletus. |
| `OverlapPolicy::Skip` | `skip` | Ohita nykyinen ajastushetki, jos käsittelijällä on odottavia tai käsittelyssä olevia töitä. `next_run` päivitetään normaalisti, jotta aikataulu pysyy tahdissa. |
| `OverlapPolicy::Buffer` | `buffer` | Kuten Skip-vaihtoehdossa, työtä ei lähetetä ja `next_run` siirtyy seuraavaan säännölliseen ajankohtaan. Toisin kuin Skip-vaihtoehdossa, `last_run` ei päivity. |

### Allow (oletus)

Saman käsittelijän useita esiintymiä voi suorittaa samanaikaisesti. Käytä tätä idempotenteille käsittelijöille, joiden päällekkäinen suoritus ei haittaa.

```php
Queuety::schedule( 'send_heartbeat_ping' )
    ->every( '1 minute' )
    ->overlap( OverlapPolicy::Allow );
```

### Skip

Ajastushetki ohitetaan äänettömästi, jos käsittelijä on yhä käynnissä. Käytä tätä käsittelijöille, joiden toisen esiintymän suorittaminen olisi turhaa tai aiheuttaisi ristiriitoja.

```php
Queuety::schedule( 'rebuild_search_index' )
    ->every( '10 minutes' )
    ->overlap( OverlapPolicy::Skip );
```

### Buffer

Toimii tällä hetkellä kuten Skip: jos käsittelijällä on yhä odottava tai käsittelyssä oleva työ, ajastushetkeä ei lähetetä ja `next_run` siirtyy seuraavaan säännölliseen ajankohtaan. Ainoa ero on, että Buffer jättää `last_run`-arvon ennalleen, kun taas Skip kirjaa ohitetun ajastushetken viimeiseksi suoritukseksi.

```php
Queuety::schedule( 'sync_inventory' )
    ->every( '5 minutes' )
    ->overlap( OverlapPolicy::Buffer );
```

## Näin se toimii

Kun aikataulu luodaan, Queuety tallentaa sen tauluun `queuety_schedules` yhdessä lausekkeen, käsittelijän, hyötykuorman ja seuraavan lasketun suoritusajan kanssa.

Jokaisella ajastimen tikillä (noin kerran minuutissa pitkäkestoisessa työntekijässä tai kun suoritat `wp queuety schedule run`) ajastin tarkistaa aikataulut, joiden `next_run` on mennyt. Jokaiselle erääntyneelle aikataululle lähetetään uusi työ, ja `next_run` päivitetään seuraavaan esiintymään.

## Aikataulujen hallinta CLI-toiminnolla

```bash
# List all schedules
wp queuety schedule list

# Add a recurring schedule
wp queuety schedule add cleanup_handler --every="1 hour"
wp queuety schedule add nightly_report --cron="0 3 * * *" --queue=reports

# Remove a schedule
wp queuety schedule remove cleanup_handler

# Manually trigger the scheduler
wp queuety schedule run
```

## Aikataulujen hallinta PHP-toiminnolla

```php
// Get the scheduler instance
$scheduler = Queuety::scheduler();

// List all schedules
$schedules = $scheduler->list();

// Remove a schedule by handler name
$scheduler->remove( 'cleanup_handler' );

// Manually trigger a tick
$count = $scheduler->tick();
```

## Hyötykuorma

Aikatauluihin voi liittää staattisen hyötykuorman, joka välitetään jokaiselle lähetetylle työlle:

```php
Queuety::schedule( 'generate_report', [ 'type' => 'daily', 'format' => 'pdf' ] )
    ->every( '1 day' )
    ->on_queue( 'reports' );
```

Aina aikataulun käynnistyessä lähetetään uusi työ tämän hyötykuorman kanssa.
