
# Προσωρινή αποθήκευση

Το Queuety περιλαμβάνει ένα επίπεδο cache που μειώνει τα ερωτήματα βάσης δεδομένων σε διαδρομές υψηλής συχνότητας, όπως οι έλεγχοι παύσης ουράς, οι μετρητές ορίων ρυθμού, οι αναζητήσεις κατάστασης ροής εργασιών και οι λειτουργίες κλειδώματος. Η cache αρχικοποιείται αυτόματα όταν καλείτε το `Queuety::init()`.

## Διεπαφή cache

Όλα τα backend cache υλοποιούν το `Queuety\Contracts\Cache`:

| Μέθοδος | Επιστρέφει | Περιγραφή |
|---|---|---|
| `get( string $key )` | `mixed` | Ανακτά μια τιμή. Επιστρέφει `null` αν δεν βρεθεί ή έχει λήξει. |
| `set( string $key, mixed $value, int $ttl = 0 )` | `void` | Αποθηκεύει μια τιμή. TTL 0 σημαίνει ότι δεν υπάρχει λήξη. |
| `delete( string $key )` | `void` | Αφαιρεί μια τιμή. |
| `has( string $key )` | `bool` | Ελέγχει αν υπάρχει ένα κλειδί και δεν έχει λήξει. |
| `add( string $key, mixed $value, int $ttl = 0 )` | `bool` | Ορίζει μια τιμή μόνο αν το κλειδί δεν υπάρχει ήδη (ατομικά). Επιστρέφει `true` αν ορίστηκε η τιμή. |
| `flush()` | `void` | Αφαιρεί όλα τα στοιχεία από την cache. Το `ApcuCache::flush()` καλεί το `apcu_clear_cache()`, το οποίο εκκαθαρίζει κάθε καταχώριση APCu στον διακομιστή και όχι μόνο του Queuety. |

## Ενσωματωμένα backend

### MemoryCache (προεπιλογή)

Το `Queuety\Cache\MemoryCache` είναι cache ανά διεργασία, βασισμένη σε πίνακα. Τα στοιχεία αποθηκεύονται σε πίνακα PHP και χάνονται όταν τερματιστεί η διεργασία. Είναι το προεπιλεγμένο backend όταν το APCu δεν είναι διαθέσιμο.

Δεν απαιτεί επεκτάσεις, λειτουργεί καλά σε αναπτύξεις με έναν worker και διατηρεί κάθε διεργασία worker απομονωμένη από τις υπόλοιπες.

### ApcuCache

Το `Queuety\Cache\ApcuCache` χρησιμοποιεί την επέκταση APCu για κοινόχρηστη μνήμη μεταξύ όλων των διεργασιών PHP στον ίδιο διακομιστή. Όλα τα κλειδιά λαμβάνουν αυτόματα το πρόθεμα `queuety:` για την αποφυγή διενέξεων με άλλες εφαρμογές.

Αυτό το backend απαιτεί την επέκταση `php-apcu`, μοιράζεται καταχωρίσεις cache μεταξύ worker στον ίδιο διακομιστή και καθιστά το `add()` πραγματικά ατομικό μέσω του `apcu_add()`.

## Αυτόματος εντοπισμός

Το `Queuety\Cache\CacheFactory` επιλέγει αυτόματα το καλύτερο διαθέσιμο backend:

Αν υπάρχει το `apcu_store()` και το `apcu_enabled()` επιστρέψει `true`, το Queuety χρησιμοποιεί το `ApcuCache`. Διαφορετικά, καταφεύγει στο `MemoryCache`. Αυτό συμβαίνει μέσα στο `Queuety::init()`, οπότε η προεπιλεγμένη συμπεριφορά δεν απαιτεί πρόσθετη ρύθμιση.

## Τι αποθηκεύεται στην cache

Το επίπεδο cache χρησιμοποιείται εσωτερικά από διάφορα υποσυστήματα:

| Δεδομένα | Σκοπός |
|---|---|
| Κατάσταση παύσης ουράς | Αποφεύγει ερώτημα βάσης δεδομένων σε κάθε επανάληψη του βρόχου worker |
| Μετρητές ορίων ρυθμού | Παρακολουθούν τον αριθμό εκτελέσεων στη μνήμη αντί στη βάση δεδομένων |
| Κατάσταση ροής εργασιών | Μειώνει τις αναγνώσεις κατά την προώθηση ροών εργασιών πολλών βημάτων |
| Κατάσταση κλειδώματος | Επιταχύνει τους ελέγχους ύπαρξης κλειδώματος για μοναδικές εργασίες και middleware αμοιβαίου αποκλεισμού |

## Ρύθμιση TTL

Το προεπιλεγμένο TTL της cache είναι 5 δευτερόλεπτα. Ισχύει για την κατάσταση παύσης ουράς και τους μετρητές ορίων ρυθμού· οι αναγνώσεις κατάστασης ροής εργασιών αποθηκεύονται στην cache για σταθερά 2 δευτερόλεπτα, τιμή που δεν αλλάζει με τη σταθερά. Παρακάμψτε την προεπιλογή με τη σταθερά `QUEUETY_CACHE_TTL` στο `wp-config.php` σας:

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

Μικρότερο TTL σημαίνει συχνότερα ερωτήματα στη βάση δεδομένων αλλά πιο πρόσφατα δεδομένα. Μεγαλύτερο TTL μειώνει τον φόρτο της βάσης δεδομένων, αλλά εισάγει περισσότερη παλαιότητα. Για τις περισσότερες αναπτύξεις, η προεπιλογή των 5 δευτερολέπτων αποτελεί καλή ισορροπία.

## Προσαρμοσμένο backend cache

Για να χρησιμοποιήσετε προσαρμοσμένο backend cache (Redis, Memcached ή οποιοδήποτε άλλο), υλοποιήστε τη διεπαφή `Contracts\Cache` και καλέστε το `Queuety::set_cache()` πριν από το `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 );
```

Αν κληθεί το `set_cache()` πριν από το `init()`, παραλείπεται εντελώς ο αυτόματος εντοπισμός από το factory και χρησιμοποιείται το προσαρμοσμένο backend.

## Πρόσβαση στην cache

Ανακτήστε ανά πάσα στιγμή το ενεργό στιγμιότυπο cache:

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

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

Αυτό επιστρέφει το backend που είναι ενεργό εκείνη τη στιγμή (MemoryCache, ApcuCache ή τη δική σας υλοποίηση).
