Handlery, hooky, stampy a snapshoty
Handler prechodu beží v transakcii po zápise stavu; implementujte CompensatesTransition, aby sa dal vrátiť. Stampy nastavia stĺpce na „teraz“ pri vstupe a snapshoty zachytia atribúty, aby ich rollback mohol obnoviť:
use RoundlyConsulting\Lifecycle\Contracts\CompensatesTransition;
use RoundlyConsulting\Lifecycle\Contracts\TransitionHandler;
use RoundlyConsulting\Lifecycle\DataTransferObjects\RollbackContext;
use RoundlyConsulting\Lifecycle\DataTransferObjects\TransitionContext;
final readonly class ReserveStock implements TransitionHandler, CompensatesTransition
{
public function __construct(private Inventory $inventory) {}
public function handle(TransitionContext $context): void
{
$this->inventory->reserve($context->subject);
}
public function compensate(RollbackContext $context): void
{
$this->inventory->release($context->subject);
}
}
$lifecycle->state(OrderStatus::Paid)->stamps('paid_at')->onEnter(SendReceipt::class);
$lifecycle->transition('fulfil')
->from(OrderStatus::Paid)->to(OrderStatus::Fulfilled)
->handledBy(ReserveStock::class)
->snapshots('stock_note')
->reversible(within: '1 hour');Transakcia
V jednej transakcii na pripojení subjektu apply() urobí toto:
- 1. Zamkne riadok subjektu.
- 2. Znova overí prechod.
- 3. Odošle LifecycleTransitioning.
- 4. Zapíše stav cez compare-and-swap.
- 5. Spustí hooky onExit, handler a hooky onEnter.
- 6. Uloží model, ak má neuložené zmeny.
- 7. Pridá riadok histórie.
- 8. Aktualizuje záznam stavu a plány.
Udalosti sa potom odošlú po commite. Ak čokoľvek vyhodí výnimku, všetko sa vráti vrátane modelu v pamäti. Externé vedľajšie efekty (e-maily, HTTP volania) držte v listeneroch udalostí po commite: opakovanie po deadlocku spustí handlery znova.
Pravidlá
- Handlery, guardy a hooky zadané názvom triedy sa z kontajnera získavajú pri každom behu, takže funguje injektovanie cez konštruktor aj prepísanie v kontajneri. Fungujú aj inštancie a closures.
- Zmeny modelu z handlera sa uložia po ňom; jeho výnimky vrátia všetko.
- Handler ani hook nesmie zmeniť práve zapisovaný atribút cyklu: InvalidLifecycleUsageException::dirtyStateAttribute a prechod sa vráti — so striktnými zápismi aj bez nich. To isté platí pre kompenzačný handler počas rollbacku. Každý iný model aj každý iný cyklus toho istého modelu si v handleroch ponechá striktné zápisy.
- Pri vstupe do stavu s kvótou vyhodí handler či hook, ktorý zmení stĺpec scope kvóty, InvalidLifecycleUsageException::quotaScopeChanged.
- Bez CompensatesTransition (alebo reversible(withoutCompensation: true)) sa prechod s handlerom nedá vrátiť — lifecycle:validate upozorní irreversible_by_handler. Handler ako closure kompenzovať nevie.
- Prechody do toho istého stavu spustia handler, ale žiadne hooky, pretože sa žiadny stav neopúšťa ani nevstupuje. Inicializácia, adopcia a rollbacky nespúšťajú hooky; inicializácia a adopcia nenastavujú stampy.
- Hooky onEnter / onExit implementujú StateHook (__invoke(StateHookContext $context)) a dostanú subject, lifecycle, state a TransitionContext.
- Stampy sa vždy zachytia do snapshotu, takže ich rollback obnoví.
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 kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
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.