
# Περιορισμός ρυθμού

Το Queuety υποστηρίζει περιορισμό ρυθμού ανά χειριστή, ώστε να αποτρέπεται η υπερφόρτωση εξωτερικών API ή άλλων περιορισμένων πόρων. Όταν ένας χειριστής φτάσει το όριό του, οι εργαζόμενοι αφήνουν τις εργασίες του σε εκκρεμότητα και τις αναλαμβάνουν ξανά μόλις το επιτρέψει το χρονικό παράθυρο.

## Ορισμός ορίου ρυθμού

Εφαρμόστε όριο ρυθμού κατά την αποστολή μιας εργασίας:

```php
use Queuety\Queuety;

Queuety::dispatch( 'call_openai', $payload )
    ->rate_limit( 10, 60 ); // max 10 executions per 60 seconds
```

Τα δύο ορίσματα είναι:
1. `$max` - Μέγιστος αριθμός εκτελέσεων που επιτρέπονται στο χρονικό παράθυρο
2. `$window` - Διάρκεια παραθύρου σε δευτερόλεπτα

Ένα όριο που ορίζεται κατά την αποστολή καταχωρίζεται μόνο στη διεργασία PHP που αποστέλλει την εργασία. Ένας εργαζόμενος που εκτελείται σε ξεχωριστή διεργασία, όπως το `wp queuety work`, δεν το βλέπει· επομένως, ορίστε στον χειριστή το `config()` για όρια που πρέπει να ισχύουν μεταξύ διεργασιών, όπως φαίνεται παρακάτω ([#3](https://github.com/inline0/queuety/issues/3)).

## Όρια ρυθμού σε επίπεδο χειριστή

Ορίστε όρια ρυθμού στη μέθοδο `config()` του χειριστή, ώστε να ισχύουν για κάθε αποστολή:

```php
use Queuety\Handler;

class CallOpenAIHandler implements Handler {
    public function handle( array $payload ): void {
        // Call the API...
    }

    public function config(): array {
        return [
            'rate_limit' => [ 60, 60 ], // 60 requests per minute
        ];
    }
}
```

## Πώς λειτουργεί

Τα όρια ρυθμού παρακολουθούνται ανά όνομα χειριστή. Αφού αναλάβει μια εργασία, ο εργαζόμενος καταχωρίζει το όριο του χειριστή (από το `config()` του) και ελέγχει τον περιοριστή ρυθμού. Αν ο χειριστής έχει φτάσει το όριό του, ο εργαζόμενος επιστρέφει αμέσως την εργασία στο `pending` χωρίς καθυστέρηση και χωρίς να καταναλώσει προσπάθεια, έπειτα περιμένει `QUEUETY_WORKER_SLEEP` δευτερόλεπτα πριν από την επόμενη αναζήτηση. Αν ο εργαζόμενος ξεκίνησε με το `--once`, τερματίζεται αντί να περιμένει.

Κάθε εργαζόμενος διατηρεί έναν μετρητή στη μνήμη και τον ανανεώνει κάθε 5 δευτερόλεπτα από τον πίνακα `queuety_logs`, μετρώντας τις εγγραφές καταγραφής `completed` του χειριστή των τελευταίων `$window` δευτερολέπτων. Επειδή η μέτρηση βασίζεται στον κοινόχρηστο πίνακα καταγραφών (και στην κοινόχρηστη μνήμη cache, αν έχει ρυθμιστεί), τα όρια σε επίπεδο χειριστή επιβάλλονται σε όλες τις διεργασίες εργαζομένων και όχι μόνο σε έναν εργαζόμενο. Οι αποτυχημένες εκτελέσεις δεν προσμετρώνται στο όριο.

## Προγραμματιστική πρόσβαση

Αποκτήστε απευθείας πρόσβαση στον περιοριστή ρυθμού:

```php
$limiter = Queuety::rate_limiter();

// Register a rate limit
$limiter->register( 'call_openai', 60, 60 );

// Check whether a handler has reached its limit
$limited = $limiter->is_limited( 'call_openai' ); // true while the limit is reached

// Seconds until the current window resets
$wait = $limiter->time_until_available( 'call_openai' );
```

Τα `register()` και `is_limited()` ενεργούν στον περιοριστή της τρέχουσας διεργασίας PHP. Η καταχώριση ενός ορίου εδώ δεν αλλάζει όσα επιβάλλει ένας εργαζόμενος που εκτελείται ξεχωριστά.

## Περιπτώσεις χρήσης

- **Όρια εξωτερικών API.** Αντιστοιχίστε το όριο ρυθμού σας στο όριο χρήσης του API (π.χ. e.g, 60 RPM του OpenAI).
- **Περιορισμός αποστολής email.** Αποτρέψτε την αποστολή υπερβολικά πολλών email σε σύντομο χρονικό διάστημα.
- **Προστασία πόρων.** Περιορίστε τους χειριστές που απαιτούν πολλή CPU, ώστε να μην παραμερίζονται άλλες εργασίες.
