
# Buforowanie

Queuety zawiera warstwę pamięci podręcznej, która ogranicza zapytania do bazy danych na często używanych ścieżkach, takich jak sprawdzanie wstrzymania kolejki, liczniki limitów żądań, odczyty stanu przepływu pracy i operacje blokad. Pamięć podręczna jest inicjowana automatycznie po wywołaniu `Queuety::init()`.

## Interfejs pamięci podręcznej

Wszystkie backendy pamięci podręcznej implementują `Queuety\Contracts\Cache`:

| Metoda | Zwraca | Opis |
|---|---|---|
| `get( string $key )` | `mixed` | Pobiera wartość. Zwraca `null`, jeśli jej nie znaleziono lub wygasła. |
| `set( string $key, mixed $value, int $ttl = 0 )` | `void` | Zapisuje wartość. TTL równy 0 oznacza brak wygaśnięcia. |
| `delete( string $key )` | `void` | Usuwa wartość. |
| `has( string $key )` | `bool` | Sprawdza, czy klucz istnieje i nie wygasł. |
| `add( string $key, mixed $value, int $ttl = 0 )` | `bool` | Ustawia wartość tylko wtedy, gdy klucz jeszcze nie istnieje (atomowo). Zwraca `true`, jeśli wartość została ustawiona. |
| `flush()` | `void` | Usuwa wszystkie elementy z pamięci podręcznej. `ApcuCache::flush()` wywołuje `apcu_clear_cache()`, które czyści każdy wpis APCu na serwerze, a nie tylko wpisy Queuety. |

## Wbudowane backendy

### MemoryCache (domyślnie)

`Queuety\Cache\MemoryCache` to pamięć podręczna oparta na tablicy, działająca osobno w każdym procesie. Elementy są przechowywane w tablicy PHP i tracone po zakończeniu procesu. Jest to domyślny backend, gdy APCu jest niedostępne.

Nie wymaga rozszerzeń, dobrze działa we wdrożeniach z jednym workerem i izoluje procesy workerów od siebie.

### ApcuCache

`Queuety\Cache\ApcuCache` używa rozszerzenia APCu do współdzielenia pamięci przez wszystkie procesy PHP na tym samym serwerze. Wszystkie klucze są automatycznie poprzedzane `queuety:`, aby uniknąć konfliktów z innymi aplikacjami.

Ten backend wymaga rozszerzenia `php-apcu`, współdzieli wpisy pamięci podręcznej między workerami na tym samym serwerze i zapewnia pełną atomowość `add()` za pomocą `apcu_add()`.

## Automatyczne wykrywanie

`Queuety\Cache\CacheFactory` automatycznie wybiera najlepszy dostępny backend:

Jeśli `apcu_store()` istnieje, a `apcu_enabled()` zwraca `true`, Queuety używa `ApcuCache`. W przeciwnym razie przechodzi na `MemoryCache`. Dzieje się to wewnątrz `Queuety::init()`, więc domyślne działanie nie wymaga dodatkowej konfiguracji.

## Co jest buforowane

Warstwa pamięci podręcznej jest używana wewnętrznie przez kilka podsystemów:

| Dane | Cel |
|---|---|
| Stan wstrzymania kolejki | Unika zapytania do bazy danych w każdej iteracji pętli workera |
| Liczniki limitów żądań | Śledzą liczbę wykonań w pamięci zamiast w bazie danych |
| Stan przepływu pracy | Ogranicza odczyty podczas przechodzenia przez wieloetapowy przepływ pracy |
| Stan blokady | Przyspiesza sprawdzanie istnienia blokad dla unikatowych zadań i oprogramowania pośredniczącego mutex |

## Konfiguracja TTL

Domyślny TTL pamięci podręcznej wynosi 5 sekund. Dotyczy stanu wstrzymania kolejki i liczników limitów żądań; odczyty stanu i statusu przepływu pracy są buforowane przez stałe 2 sekundy, których tej stałej nie można zmienić. Zmień wartość domyślną za pomocą stałej `QUEUETY_CACHE_TTL` w pliku `wp-config.php`:

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

Niższy TTL oznacza częstsze zapytania do bazy danych, ale świeższe dane. Wyższy TTL zmniejsza obciążenie bazy, ale zwiększa ryzyko nieaktualnych danych. W większości wdrożeń domyślne 5 sekund stanowi dobry kompromis.

## Niestandardowy backend pamięci podręcznej

Aby użyć niestandardowego backendu pamięci podręcznej (Redis, Memcached lub dowolnego innego), zaimplementuj interfejs `Contracts\Cache` i wywołaj `Queuety::set_cache()` przed `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 );
```

Jeśli wywołasz `set_cache()` przed `init()`, automatyczne wykrywanie w fabryce zostanie całkowicie pominięte i zostanie użyty Twój niestandardowy backend.

## Dostęp do pamięci podręcznej

W dowolnym momencie pobierz aktywną instancję pamięci podręcznej:

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

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

Zwraca to aktualnie aktywny backend (MemoryCache, ApcuCache lub Twoją własną implementację).
