
# Compensarea fluxurilor de lucru

Compensarea vă permite să atașați un gestionar de revenire la un pas finalizat al fluxului de lucru. Queuety stochează un instantaneu al stării publice la finalizarea pasului, apoi rulează gestionarii de compensare în ordine inversă când fluxul de lucru este anulat sau, opțional, când eșuează.

## Metoda `compensate_with()`

Apelați `compensate_with()` imediat după pasul pe care trebuie să-l anuleze:

```php
use Queuety\Queuety;

Queuety::workflow( 'provision_account' )
    ->then( CreateRemoteUserStep::class )
    ->compensate_with( DeleteRemoteUserCompensation::class )
    ->then( CreateSubscriptionStep::class )
    ->compensate_with( CancelSubscriptionCompensation::class )
    ->then( SendWelcomeEmailStep::class )
    ->dispatch( [ 'user_id' => 42 ] );
```

Dacă fluxul de lucru este anulat ulterior, Queuety rulează:

1. `CancelSubscriptionCompensation`
2. `DeleteRemoteUserCompensation`

## Gestionari de compensare

Gestionarii de compensare implementează `Contracts\Compensation`:

```php
use Queuety\Contracts\Compensation;

final class DeleteRemoteUserCompensation implements Compensation {
    public function handle( array $state ): void {
        remote_api_delete_user( $state['remote_user_id'] );
    }
}
```

Gestionarul primește starea publică a fluxului de lucru așa cum era imediat după finalizarea pasului compensat. Cheile interne rezervate nu sunt incluse.

## Anulare sau eșec

La anularea explicită, compensările pașilor finalizați rulează întotdeauna înaintea gestionarului opțional `on_cancel()`.

La eșec, compensările rulează numai dacă optați pentru aceasta:

```php
Queuety::workflow( 'provision_account' )
    ->then( CreateRemoteUserStep::class )
    ->compensate_with( DeleteRemoteUserCompensation::class )
    ->then( CreateSubscriptionStep::class )
    ->compensate_with( CancelSubscriptionCompensation::class )
    ->then( ChargeCardStep::class )
    ->compensate_on_failure()
    ->dispatch( $payload );
```

Fără `compensate_on_failure()`, un flux de lucru eșuat își păstrează intact istoricul pașilor finalizați și poate fi reîncercat începând de la pasul eșuat.

Cu `compensate_on_failure()`, compensările pașilor finalizați rulează după ce fluxul de lucru este marcat ca eșuat. După aceea, `retry_workflow()` aruncă o excepție deoarece fluxul de lucru a fost deja compensat.

## Tipuri de pași acceptate

Compensarea poate fi atașată la:

- pași secvențiali `then()`
- grupuri `parallel()`
- pași `for_each()`
- pași `run_workflow()`
- pași de întârziere `delay()`
- pași de semnal `wait_for_signal()`
- pași de dependență între fluxuri de lucru `wait_for_workflow()`

Pentru `run_workflow()` și `for_each()`, instantaneul pentru compensare este înregistrat după ce activitatea imbricată sau ramificată s-a încheiat complet.

## `on_cancel()` sau compensare

Folosiți `compensate_with()` pentru a anula efectele secundare ale pașilor finalizați, în ordine inversă.

Folosiți `on_cancel()` pentru un singur cârlig de curățare la nivel de flux de lucru, care trebuie să ruleze ori de câte ori fluxul este anulat explicit.
