
# Caching

Queuety menyertakan lapisan cache yang mengurangi kueri basis data pada jalur yang sering digunakan, seperti pemeriksaan jeda antrean, penghitung batas laju, pencarian status alur kerja, dan operasi kunci. Cache diinisialisasi secara otomatis saat Anda memanggil `Queuety::init()`.

## Antarmuka cache

Semua backend cache mengimplementasikan `Queuety\Contracts\Cache`:

| Metode | Mengembalikan | Deskripsi |
|---|---|---|
| `get( string $key )` | `mixed` | Ambil sebuah nilai. Mengembalikan `null` jika tidak ditemukan atau sudah kedaluwarsa. |
| `set( string $key, mixed $value, int $ttl = 0 )` | `void` | Simpan sebuah nilai. TTL 0 berarti tidak kedaluwarsa. |
| `delete( string $key )` | `void` | Hapus sebuah nilai. |
| `has( string $key )` | `bool` | Periksa apakah kunci ada dan belum kedaluwarsa. |
| `add( string $key, mixed $value, int $ttl = 0 )` | `bool` | Tetapkan nilai hanya jika kunci belum ada (atomik). Mengembalikan `true` jika nilai berhasil ditetapkan. |
| `flush()` | `void` | Hapus semua item dari cache. `ApcuCache::flush()` memanggil `apcu_clear_cache()`, yang menghapus setiap entri APCu di server, bukan hanya milik Queuety. |

## Backend bawaan

### MemoryCache (default)

`Queuety\Cache\MemoryCache` adalah cache berbasis array untuk setiap proses. Item disimpan dalam array PHP dan hilang saat proses berakhir. Ini adalah backend default saat APCu tidak tersedia.

Backend ini tidak memerlukan ekstensi, berfungsi baik untuk deployment dengan satu worker, dan menjaga setiap proses worker tetap terisolasi dari yang lain.

### ApcuCache

`Queuety\Cache\ApcuCache` menggunakan ekstensi APCu untuk berbagi memori di antara semua proses PHP pada server yang sama. Semua kunci otomatis diawali dengan `queuety:` untuk menghindari konflik dengan aplikasi lain.

Backend ini memerlukan ekstensi `php-apcu`, berbagi entri cache di antara worker pada server yang sama, dan membuat `add()` benar-benar atomik melalui `apcu_add()`.

## Deteksi otomatis

`Queuety\Cache\CacheFactory` memilih backend terbaik yang tersedia secara otomatis:

Jika `apcu_store()` tersedia dan `apcu_enabled()` mengembalikan `true`, Queuety menggunakan `ApcuCache`. Jika tidak, sistem beralih ke `MemoryCache`. Proses ini berlangsung di dalam `Queuety::init()`, sehingga perilaku default tidak memerlukan konfigurasi tambahan.

## Data yang di-cache

Lapisan cache digunakan secara internal oleh beberapa subsistem:

| Data | Tujuan |
|---|---|
| Status jeda antrean | Menghindari kueri basis data pada setiap iterasi worker |
| Penghitung batas laju | Melacak jumlah eksekusi di memori, bukan di basis data |
| Status alur kerja | Mengurangi pembacaan saat alur kerja bertahap dilanjutkan |
| Status kunci | Mempercepat pemeriksaan keberadaan kunci untuk pekerjaan unik dan middleware mutex |

## Konfigurasi TTL

TTL cache default adalah 5 detik. TTL ini berlaku untuk status jeda antrean dan penghitung batas laju; pembacaan status dan keadaan alur kerja di-cache selama 2 detik tetap, yang tidak diubah oleh konstanta. Ganti nilai default dengan konstanta `QUEUETY_CACHE_TTL` di `wp-config.php` Anda:

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

TTL yang lebih rendah berarti kueri basis data lebih sering, tetapi data lebih baru. TTL yang lebih tinggi mengurangi beban basis data, tetapi membuat data lebih usang. Untuk sebagian besar deployment, nilai default 5 detik merupakan keseimbangan yang baik.

## Backend cache kustom

Untuk menggunakan backend cache kustom (Redis, Memcached, atau yang lain), implementasikan antarmuka `Contracts\Cache` dan panggil `Queuety::set_cache()` sebelum `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 );
```

Jika `set_cache()` dipanggil sebelum `init()`, deteksi otomatis factory dilewati sepenuhnya dan backend kustom Anda akan digunakan.

## Mengakses cache

Ambil instance cache aktif kapan saja:

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

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

Ini mengembalikan backend yang sedang aktif (MemoryCache, ApcuCache, atau implementasi kustom Anda).
