
# Memorare în cache

Queuety include un strat de cache care reduce interogările bazei de date pe căile frecvent accesate, precum verificările de suspendare a cozii, contoarele de limitare a ratei, căutările stării fluxurilor de lucru și operațiile de blocare. Cache-ul se inițializează automat când apelați `Queuety::init()`.

## Interfața cache-ului

Toate backend-urile de cache implementează `Queuety\Contracts\Cache`:

| Metodă | Returnează | Descriere |
|---|---|---|
| `get( string $key )` | `mixed` | Preia o valoare. Returnează `null` dacă nu este găsită sau a expirat. |
| `set( string $key, mixed $value, int $ttl = 0 )` | `void` | Stochează o valoare. Un TTL de 0 înseamnă că nu expiră. |
| `delete( string $key )` | `void` | Elimină o valoare. |
| `has( string $key )` | `bool` | Verifică dacă o cheie există și nu a expirat. |
| `add( string $key, mixed $value, int $ttl = 0 )` | `bool` | Setează o valoare doar dacă cheia nu există deja (atomic). Returnează `true` dacă valoarea a fost setată. |
| `flush()` | `void` | Elimină toate elementele din cache. `ApcuCache::flush()` apelează `apcu_clear_cache()`, care șterge fiecare intrare APCu de pe server, nu doar intrările Queuety. |

## Backend-uri integrate

### MemoryCache (implicit)

`Queuety\Cache\MemoryCache` este un cache per proces, bazat pe array. Elementele sunt stocate într-un array PHP și se pierd la încheierea procesului. Acesta este backend-ul implicit când APCu nu este disponibil.

Nu necesită extensii, funcționează bine pentru implementări cu un singur worker și menține fiecare proces worker izolat de celelalte.

### ApcuCache

`Queuety\Cache\ApcuCache` folosește extensia APCu pentru memorie partajată între toate procesele PHP de pe același server. Toate cheile primesc automat prefixul `queuety:` pentru a evita conflictele cu alte aplicații.

Acest backend necesită extensia `php-apcu`, partajează intrările cache-ului între worker-ele de pe același server și face ca `add()` să fie cu adevărat atomic prin `apcu_add()`.

## Detectare automată

`Queuety\Cache\CacheFactory` alege automat cel mai bun backend disponibil:

Dacă `apcu_store()` există și `apcu_enabled()` returnează `true`, Queuety folosește `ApcuCache`. În caz contrar, revine la `MemoryCache`. Acest lucru are loc în `Queuety::init()`, deci comportamentul implicit nu necesită configurare suplimentară.

## Ce se pune în cache

Stratul de cache este folosit intern de mai multe subsisteme:

| Date | Scop |
|---|---|
| Starea de suspendare a cozii | Evită interogarea bazei de date la fiecare iterație a buclei worker-ului |
| Contoare de limitare a ratei | Urmărește numărul de execuții în memorie, nu în baza de date |
| Starea fluxului de lucru | Reduce citirile în timpul avansării fluxurilor de lucru cu mai mulți pași |
| Starea blocării | Accelerează verificările existenței blocărilor pentru activități unice și middleware-ul mutex |

## Configurarea TTL

TTL-ul implicit al cache-ului este de 5 secunde. Se aplică stării de suspendare a cozii și contoarelor de limitare a ratei; citirile stării și ale statutului fluxului de lucru sunt memorate în cache timp de 2 secunde, o valoare fixă pe care constanta nu o modifică. Suprascrieți valoarea implicită cu constanta `QUEUETY_CACHE_TTL` din `wp-config.php`:

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

Un TTL mai mic înseamnă interogări mai frecvente ale bazei de date, dar date mai recente. Un TTL mai mare reduce încărcarea bazei de date, dar face ca datele să fie mai vechi. Pentru majoritatea implementărilor, valoarea implicită de 5 secunde oferă un echilibru bun.

## Backend de cache personalizat

Pentru a folosi un backend de cache personalizat (Redis, Memcached sau oricare altul), implementați interfața `Contracts\Cache` și apelați `Queuety::set_cache()` înainte de `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 );
```

Dacă se apelează `set_cache()` înainte de `init()`, detectarea automată a fabricii este omisă complet și se folosește backend-ul personalizat.

## Accesarea cache-ului

Preluați oricând instanța activă a cache-ului:

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

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

Aceasta returnează backend-ul activ în acel moment (MemoryCache, ApcuCache sau implementarea dvs. personalizată).
