
# Darbplūsmas kompensācija

Kompensācija ļauj pabeigtai darbplūsmas darbībai pievienot atcelšanas apstrādātāju. Queuety saglabā publiskā stāvokļa momentuzņēmumu, kad darbība ir pabeigta, un pēc tam apgrieztā secībā palaiž kompensācijas apstrādātājus, kad darbplūsma tiek atcelta vai, pēc izvēles, kad tā beidzas ar kļūdu.

## Metode `compensate_with()`

Izsauciet `compensate_with()` uzreiz pēc darbības, kuru tai jāatceļ:

```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 ] );
```

Ja darbplūsma vēlāk tiek atcelta, tiek palaista Queuety:

1. `CancelSubscriptionCompensation`
2. `DeleteRemoteUserCompensation`

## Kompensācijas apstrādātāji

Kompensācijas apstrādātāji implementē `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'] );
    }
}
```

Apstrādātājs saņem publisko darbplūsmas stāvokli tādu, kāds tas bija uzreiz pēc kompensētās darbības pabeigšanas. Rezervētās iekšējās atslēgas nav iekļautas.

## Atcelšana un kļūme

Skaidras atcelšanas gadījumā pabeigto darbību kompensācijas vienmēr tiek izpildītas pirms izvēles `on_cancel()` apstrādātāja.

Kļūmes gadījumā kompensācijas tiek izpildītas tikai tad, ja to izvēlaties:

```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 );
```

Bez `compensate_on_failure()` darbplūsma ar kļūdu saglabā pabeigto darbību vēsturi, un to var atkārtot no darbības, kurā radās kļūda.

Ar `compensate_on_failure()` pabeigto darbību kompensācijas tiek izpildītas pēc tam, kad darbplūsma atzīmēta kā neveiksmīga. Pēc tam `retry_workflow()` izmet kļūdu, jo darbplūsmai jau ir veikta kompensācija.

## Atbalstītie darbību veidi

Kompensāciju var pievienot šādiem elementiem:

- secīgām `then()` darbībām
- `parallel()` grupām
- `for_each()` darbībām
- `run_workflow()` darbībām
- `delay()` aiztures darbībām
- `wait_for_signal()` signāla darbībām
- `wait_for_workflow()` darbplūsmas atkarības darbībām

Attiecībā uz `run_workflow()` un `for_each()` kompensācijas momentuzņēmums tiek ierakstīts pēc tam, kad ligzdotais vai sazarotais darbs ir pilnībā pabeigts.

## `on_cancel()` un kompensācija

Izmantojiet `compensate_with()`, lai apgrieztā secībā atceltu pabeigto darbību blakusefektus.

Izmantojiet `on_cancel()` vienam darbplūsmas līmeņa tīrīšanas āķim, kas jāpalaiž ikreiz, kad darbplūsma tiek skaidri atcelta.
