
# Munkafolyamat-kompenzáció

A kompenzáció lehetővé teszi, hogy visszaállításkezelőt csatoljon egy befejezett munkafolyamat-lépéshez. A Queuety nyilvánosállapot-pillanatképet tárol a lépés befejezésekor, majd fordított sorrendben futtatja a kompenzációkezelőket, ha a munkafolyamatot megszakítják, vagy opcionálisan, ha sikertelenül zárul.

## A `compensate_with()` metódus

Hívja meg a `compensate_with()` metódust közvetlenül azután a lépés után, amelynek hatását vissza kell vonnia:

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

Ha a munkafolyamatot később megszakítják, a Queuety fut le:

1. `CancelSubscriptionCompensation`
2. `DeleteRemoteUserCompensation`

## Kompenzációkezelők

A kompenzációkezelők a `Contracts\Compensation` interfészt implementálják:

```php
use Queuety\Contracts\Compensation;

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

A kezelő a kompenzált lépés befejezése utáni állapotot kapja meg. A fenntartott belső kulcsok nem szerepelnek benne.

## Megszakítás vagy sikertelenség

Kifejezett megszakítás esetén a befejezett lépések kompenzációi mindig az opcionális `on_cancel()` kezelő előtt futnak le.

Sikertelenség esetén a kompenzációk csak akkor futnak le, ha ezt külön engedélyezi:

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

A `compensate_on_failure()` nélkül a sikertelen munkafolyamat megőrzi a befejezett lépések előzményeit, és újrapróbálható a sikertelen lépéstől.

A `compensate_on_failure()` használatával a befejezett lépések kompenzációi a munkafolyamat sikertelennek jelölése után futnak le. Ezután a `retry_workflow()` kivételt dob, mert a munkafolyamatot már kompenzálták.

## Támogatott lépéstípusok

Kompenzáció a következőkhöz csatolható:

- szekvenciális `then()` lépésekhez
- `parallel()` csoportokhoz
- `for_each()` lépésekhez
- `run_workflow()` lépésekhez
- `delay()` késleltetési lépésekhez
- `wait_for_signal()` jelzéslépésekhez
- `wait_for_workflow()` munkafolyamat-függőségi lépésekhez

A `run_workflow()` és `for_each()` esetén a kompenzációs pillanatkép a beágyazott vagy elágaztatott munka teljes befejeződése után készül el.

## `on_cancel()` vagy kompenzáció

Használja a `compensate_with()` metódust a befejezett lépések mellékhatásainak fordított sorrendű visszavonására.

Használja a `on_cancel()` metódust egyetlen munkafolyamat-szintű takarítási művelethez, amelyet minden kifejezett megszakításkor futtatni kell.
