
# Plánovanie

Queuety má vstavanú podporu opakujúcich sa úloh. Namiesto spoliehania sa na `wp_cron` sa plány ukladajú do databázy a približne raz za minútu ich vyhodnocuje dlho bežiaci proces `wp queuety work` (alebo nadradený proces skupiny workerov). `wp queuety work --once`, `wp queuety flush` a vstavaný záložný mechanizmus pluginu WP-Cron plány nevyhodnocujú ([#14](https://github.com/inline0/queuety/issues/14)); bez dlho bežiaceho workera spúšťajte `wp queuety schedule run` sami.

## Plánovanie podľa intervalu

Jednoduché plány založené na intervaloch vytvoríte pomocou `every()`. Výraz môže byť ľubovoľný reťazec kompatibilný s PHP `DateTimeImmutable::modify()`:

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

## Plánovanie pomocou Cron

Štandardné päťpolové výrazy cron vytvoríte pomocou `cron()`:

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

## Možnosti plánu

Tvorba plánu pomocou `PendingSchedule` podporuje tieto metódy:

| Metóda | Opis |
|---|---|
| `every( string $interval )` | Nastaví intervalový výraz |
| `cron( string $expression )` | Nastaví výraz cron |
| `on_queue( string $queue )` | Nastaví cieľový front (predvolené: `'default'`) |
| `overlap( OverlapPolicy $policy )` | Nastaví pravidlá prekrývania (predvolené: `Allow`) |

Pred odoslaním plánu musíte zavolať buď `every()`, alebo `cron()`. Ak nenastavíte ani jednu, vyvolá sa výnimka `RuntimeException`.

## Pravidlá prekrývania

Ak sa naplánovaná úloha stále vykonáva (čaká alebo sa spracúva) v čase ďalšieho plánovaného spustenia, pravidlá prekrývania určujú, čo sa stane. Nastavte ich pomocou metódy `overlap()`:

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

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

Výčet `OverlapPolicy` má tri možnosti:

| Pravidlo | Hodnota | Správanie |
|---|---|---|
| `OverlapPolicy::Allow` | `allow` | Vždy odošle novú úlohu, aj keď je predchádzajúci beh stále aktívny. Toto je predvolená možnosť. |
| `OverlapPolicy::Skip` | `skip` | Vynechá aktuálne spustenie, ak má obslužná rutina čakajúce alebo spracúvané úlohy. Hodnota `next_run` sa aktualizuje obvyklým spôsobom, takže plán zachová pravidelný interval. |
| `OverlapPolicy::Buffer` | `buffer` | Podobne ako pri možnosti Skip sa úloha neodošle a `next_run` sa posunie na ďalší pravidelný termín. Na rozdiel od možnosti Skip sa `last_run` neaktualizuje. |

### Allow (predvolené)

Viacero inštancií tej istej obslužnej rutiny môže bežať súbežne. Použite túto možnosť pre idempotentné obslužné rutiny, pri ktorých je prekrývanie neškodné.

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

### Skip

Naplánované spustenie sa potichu vynechá, ak obslužná rutina stále beží. Použite túto možnosť pre obslužné rutiny, pri ktorých by spustenie druhej inštancie znamenalo plytvanie zdrojmi alebo spôsobilo konflikty.

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

### Buffer

V súčasnosti sa správa rovnako ako Skip: ak má obslužná rutina čakajúcu alebo spracúvanú úlohu, naplánované spustenie sa neodošle a `next_run` sa posunie na ďalší pravidelný termín. Jediný rozdiel je, že Buffer ponechá `last_run` nezmenené, zatiaľ čo Skip zaznamená vynechané spustenie ako posledný beh.

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

## Ako to funguje

Pri vytvorení plánu ho Queuety uloží do tabuľky `queuety_schedules` spolu s výrazom, obslužnou rutinou, obsahom a nasledujúcim vypočítaným časom spustenia.

Pri každom spustení plánovača (približne raz za minútu v dlho bežiacom workerovi alebo pri spustení `wp queuety schedule run`) plánovač skontroluje plány, ktorých čas `next_run` už uplynul. Pre každý plán, ktorého termín nastal, odošle novú úlohu a aktualizuje `next_run` na nasledujúci termín.

## Správa plánov cez CLI

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

## Správa plánov cez PHP

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

## Obsah úlohy

Plány môžu obsahovať statický obsah, ktorý sa odovzdá každej odoslanej úlohe:

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

Pri každom spustení plánu sa odošle nová úloha s týmto obsahom.
