---
title: "Limity, kvóty a zmrazenie — Lifecycle for Laravel | Roundly"
description: "Maximálny počet, cooldowny, minimálny čas v stave, zapečatenie, rate limity, kvóty podľa scope odolné voči súbehu a zmrazenie cyklu."
url: https://roundly-consulting.com/sk/open-source/navody/lifecycle-for-laravel/limity-a-kvoty
language: sk
---

[Všetky balíky](https://roundly-consulting.com/sk/open-source.md)

[Lifecycle for Laravel](https://roundly-consulting.com/sk/open-source/navody/lifecycle-for-laravel.md)

# Limity, kvóty a zmrazenie

Limity sú súčasťou definície — na stave, do ktorého sa vstupuje alebo z ktorého sa odchádza, alebo na prechode:

```php
$lifecycle->state(ListingStatus::Active)
    ->quota(fn (Listing $listing): int => $listing->user->plan->max_active, scope: 'user_id')
    ->minDwell('1 hour')
    ->sealedAfter('90 days');

$lifecycle->transition('reopen')
    ->from(ListingStatus::Closed)->to(ListingStatus::Active)
    ->maxOccurrences(3)
    ->cooldown('24 hours')
    ->rateLimit(10, '1 hour', RateLimitScope::Actor);
```

| Limit | Deklarácia | Kód zamietnutia | Systémový kontext |
| --- | --- | --- | --- |
| Maximálny počet | `transition()->maxOccurrences(3)` | `max_occurrences_reached` | platí |
| Cooldown | `transition()->cooldown('24 hours')` | `cooldown_active` | preskočí sa |
| Minimálny čas v stave | `state()->minDwell('1 hour')` | `min_dwell_not_reached` | preskočí sa |
| Zapečatenie | `state()->sealedAfter('90 days')` | `sealed` | platí |
| Zmrazenie | `Lifecycles::for($m)->freeze()` | `frozen` | platí |
| Termíny | `notBefore() / notAfter()` | `not_yet_available / deadline_passed` | platí |
| Rate limit | `transition()->rateLimit(10, '1 hour')` | `rate_limited` | preskočí sa |
| Kvóta | `state()->quota(5, scope: 'user_id')` | `quota_exceeded` | platí |

Maximálny počet a cooldowny sa počítajú z počítadiel záznamu stavu, nikdy z histórie — čistenie histórie limit nikdy nevynuluje a rollback obnoví počítadlo, ktoré vrátený riadok zmenil. Časové limity sa dosiahnu, keď teraz ≥ limit, s výnimkou notAfter(): samotný termín je ešte povolený.

## Kvóty

```php
$lifecycle->state(ListingStatus::Active)
    ->quota(5, scope: 'user_id')                                              // static
    ->quota(fn (Listing $l): int => $l->user->plan->max_active, scope: 'user_id', name: 'plan'); // per subject
```

Kvóty počítajú vlastnú tabuľku subjektu: riadky v cieľovom stave s rovnakými hodnotami scope (hodnota NULL tvorí vlastnú skupinu), bez samotného subjektu a soft-deleted riadkov a bez globálnych scopes — konzolový sweep teda napočíta to isté ako request tenanta. Overujú sa, keď prechod alebo rollback do stavu vstupuje; vytvorenie, priame zápisy, obnovenie soft-deleted subjektu a prechody do toho istého stavu sa nepočítajú a kvóta na počiatočnom stave je chybou definície. Kvóta 0 odmietne každého.

Súbežné vstupy sa serializujú cez zámkový riadok pre každú hodnotu scope, takže ani nával požiadaviek limit neprekročí — overené pri skutočnej súbežnej záťaži na PostgreSQL a MySQL. Zmena stĺpca scope pri modeli, ktorý už v stave s kvótou je (presun inzerátu od používateľa A k B bežným save()), sa znova neoveruje.

Prechod do stavu s kvótou, ktorý by zároveň zmenil niektorý z jej stĺpcov scope — neuloženou úpravou modelu alebo v handleri či hooku — vyhodí InvalidLifecycleUsageException::quotaScopeChanged a nič nezmení, pretože počet aj zámok platili pre uloženú skupinu. Stĺpec uložte samostatne, pred prechodom alebo po ňom. Rollback počíta kvótu v skupine, ktorú obnoví.

## Rate limity

```php
use RoundlyConsulting\Lifecycle\Enums\RateLimitScope;

$lifecycle->transition('reopen')
    ->rateLimit(10, '1 hour', RateLimitScope::Actor)
    ->rateLimit(100, '1 day', RateLimitScope::Subject);
```

Rate limity idú cez RateLimiter Laravelu (váš cache store). Kľúč sa skladá z rate\_limits.prefix, morph typu subjektu, cyklu, prechodu, aktéra a kľúča subjektu, pričom každá časť je escapovaná: limit na aktéra sa počíta na model, cyklus a prechod a volanie bez aktéra sa počíta na subjekt — nikdy nie v jednom spoločnom koši pre všetkých volajúcich bez aktéra. Pokusy sa započítajú, len ak prejdú všetky ostatné kontroly, a nikdy sa nevracajú, ani keď transakcia neskôr zlyhá. check() sa len pozrie; systémový kontext rate limity preskakuje.

Kľúč sa spolu s prefixom cache store a príponou :timer limitera musí zmestiť do 250 znakov. Kľúč, ktorý by sa nezmestil, vyhodí InvalidLifecycleUsageException::rateLimitKeyTooLong namiesto zlyhania v cache store a lifecycle:validate ho pri uvedených modeloch nahlási — veľmi dlhým názvom tried modelov dajte alias v morph mape.

## Zmrazenie

```php
Lifecycles::for($listing)->by($moderator)->because('Under review')->freeze(until: now()->addDays(3));
Lifecycles::for($listing)->isFrozen();      // true
Lifecycles::for($listing)->frozenUntil();   // ?CarbonImmutable
Lifecycles::for($listing)->frozenReason();  // 'Under review'
Lifecycles::for($listing)->unfreeze();      // bool: whether it was frozen
```

Zmrazený cyklus odmieta prechody (frozen), pokiaľ prechod nemá ignoresFreeze(), a rollbacky, pokiaľ ho nemá každý vracaný prechod. Splatné plány počkajú na koniec zmrazenia bez spotrebovania pokusu — okrem tých, ktorých prechod má ignoresFreeze(); tie sweep spustí aj počas zmrazenia. Dôvod zmrazenia dlhší ako history.reason\_max\_length vyhodí InvalidLifecycleUsageException. Zmrazenie platí pre jeden cyklus jedného subjektu. Neoveruje sa voči pravidlám definície a aktér sa zaznamená len pre audit — freeze() autorizujte vlastnými policies.

## Zapečatenie

sealedAfter('90 days'): keď je subjekt v stave takto dlho, prechody z neho (bez ignoresSeal()) aj rollbacky z neho sa odmietnu — aj v systémovom kontexte. Stav s TTL a sealedAfter() potrebuje expiračný prechod s ignoresSeal().

## Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

[Ďalšie spôsoby podpory vrátane kryptomien](https://roundly-consulting.com/sk/podporte-nas.md)

Odoslaním daru súhlasíte s našimi [podmienkami prijímania darov](https://roundly-consulting.com/sk/podmienky-darov.md).

[Podporte našu open-source prácu (otvorí sa v novej karte)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Pridajte sa k nám na Patreone (otvorí sa v novej karte)](https://www.patreon.com/cw/roundly)

## Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.

[Ponuka do 48 hodín](https://roundly-consulting.com/sk/kontakt.md) [Prezrieť všetky balíky](https://roundly-consulting.com/sk/open-source/navody/lifecycle-for-laravel.md)
