
# Mezipaměť

Queuety obsahuje vrstvu mezipaměti, která omezuje databázové dotazy v často používaných cestách, jako jsou kontroly pozastavení fronty, počítadla limitů rychlosti, vyhledávání stavu pracovních postupů a operace se zámky. Mezipaměť se inicializuje automaticky při volání `Queuety::init()`.

## Rozhraní mezipaměti

Všechny implementace mezipaměti dodržují rozhraní `Queuety\Contracts\Cache`:

| Metoda | Návratová hodnota | Popis |
|---|---|---|
| `get( string $key )` | `mixed` | Načte hodnotu. Pokud nebyla nalezena nebo její platnost vypršela, vrátí `null`. |
| `set( string $key, mixed $value, int $ttl = 0 )` | `void` | Uloží hodnotu. TTL 0 znamená, že platnost nevyprší. |
| `delete( string $key )` | `void` | Odebere hodnotu. |
| `has( string $key )` | `bool` | Ověří, zda klíč existuje a nevypršela jeho platnost. |
| `add( string $key, mixed $value, int $ttl = 0 )` | `bool` | Nastaví hodnotu, pouze pokud klíč ještě neexistuje (atomicky). Pokud byla hodnota nastavena, vrátí `true`. |
| `flush()` | `void` | Odebere všechny položky z mezipaměti. Volání `ApcuCache::flush()` spustí `apcu_clear_cache()`, která vymaže všechny položky APCu na serveru, nejen položky Queuety. |

## Vestavěné implementace

### MemoryCache (výchozí)

`Queuety\Cache\MemoryCache` je mezipaměť založená na poli, která je samostatná pro každý proces. Položky se ukládají do pole PHP a po ukončení procesu se ztratí. Jde o výchozí implementaci, pokud není dostupné APCu.

Nevyžaduje žádná rozšíření, dobře funguje při nasazení s jedním workerem a každý proces workeru zůstává oddělený od ostatních.

### ApcuCache

`Queuety\Cache\ApcuCache` používá rozšíření APCu ke sdílení paměti mezi všemi procesy PHP na stejném serveru. Všechny klíče se automaticky označí předponou `queuety:`, aby nedocházelo ke kolizím s jinými aplikacemi.

Tato implementace vyžaduje rozšíření `php-apcu`, sdílí položky mezipaměti mezi workery na stejném serveru a díky `apcu_add()` zajišťuje skutečně atomické `add()`.

## Automatické rozpoznání

`Queuety\Cache\CacheFactory` automaticky vybere nejvhodnější dostupnou implementaci:

Pokud existuje `apcu_store()` a `apcu_enabled()` vrátí `true`, Queuety použije `ApcuCache`. Jinak přejde na `MemoryCache`. K tomu dochází uvnitř `Queuety::init()`, takže výchozí chování nevyžaduje žádnou další konfiguraci.

## Co se ukládá do mezipaměti

Vrstva mezipaměti se interně používá v několika podsystémech:

| Data | Účel |
|---|---|
| Stav pozastavení fronty | Zamezuje databázovému dotazu při každém cyklu workeru |
| Počítadla limitů rychlosti | Sledují počet spuštění v paměti místo v databázi |
| Stav pracovního postupu | Omezují čtení při postupu vícekrokovým pracovním postupem |
| Stav zámků | Urychlují kontroly existence zámků pro jedinečné úlohy a middleware mutexu |

## Konfigurace TTL

Výchozí TTL mezipaměti je 5 sekund. Platí pro stav pozastavení fronty a počítadla limitů rychlosti; čtení stavu a průběhu pracovního postupu se ukládají do mezipaměti na pevné 2 sekundy, které tato konstanta nemění. Výchozí hodnotu můžete přepsat konstantou `QUEUETY_CACHE_TTL` ve svém `wp-config.php`:

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

Nižší TTL znamená častější databázové dotazy, ale aktuálnější data. Vyšší TTL snižuje zátěž databáze, ale data mohou být zastaralejší. Výchozích 5 sekund je pro většinu nasazení dobrým kompromisem.

## Vlastní implementace mezipaměti

Chcete-li použít vlastní implementaci mezipaměti (Redis, Memcached nebo jinou), implementujte rozhraní `Contracts\Cache` a zavolejte `Queuety::set_cache()` před `Queuety::init()`:

```php
use Queuety\Contracts\Cache;
use Queuety\Queuety;

class RedisCache implements 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 { /* ... */ }
}

// Set the cache before init() so all subsystems use it.
Queuety::set_cache( new RedisCache() );
Queuety::init( $connection );
```

Pokud zavoláte `set_cache()` před `init()`, automatické rozpoznání implementace se zcela přeskočí a použije se vaše vlastní implementace.

## Přístup k mezipaměti

Aktivní instanci mezipaměti můžete kdykoli načíst:

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

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

Vrátí aktuálně aktivní implementaci (MemoryCache, ApcuCache nebo vaši vlastní implementaci).
