Aller au contenu

Compensation de workflow

La compensation permet d’associer un gestionnaire d’annulation à une étape de workflow terminée. Queuety enregistre un instantané de l’état public à la fin de cette étape, puis exécute les gestionnaires de compensation dans l’ordre inverse lorsque le workflow est annulé ou, éventuellement, lorsqu’il échoue.

La méthode compensate_with()

Appelez compensate_with() immédiatement après l’étape qu’il doit annuler :

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

Si le workflow est annulé ultérieurement, Queuety s’exécute :

  1. CancelSubscriptionCompensation
  2. DeleteRemoteUserCompensation

Gestionnaires de compensation

Les gestionnaires de compensation implémentent 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'] );
    }
}

Le gestionnaire reçoit l’état public du workflow tel qu’il était immédiatement après l’achèvement de l’étape compensée. Les clés internes réservées ne sont pas incluses.

Annulation ou échec

En cas d’annulation explicite, les compensations des étapes terminées s’exécutent toujours avant le gestionnaire facultatif on_cancel().

En cas d’échec, les compensations ne s’exécutent que si vous les activez :

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

Sans compensate_on_failure(), un workflow en échec conserve l’historique de ses étapes terminées et peut être relancé depuis l’étape en échec.

Avec compensate_on_failure(), les compensations des étapes terminées s’exécutent après le passage du workflow à l’état d’échec. Ensuite, retry_workflow() lève une exception, car le workflow a déjà été compensé.

Types d’étapes pris en charge

La compensation peut être associée aux éléments suivants :

  • étapes then() séquentielles
  • groupes parallel()
  • étapes for_each()
  • étapes run_workflow()
  • étapes delay() de délai
  • étapes wait_for_signal() de signal
  • étapes wait_for_workflow() de dépendance de workflow

Pour run_workflow() et for_each(), l’instantané de compensation est enregistré une fois le travail imbriqué ou ramifié entièrement terminé.

on_cancel() ou compensation

Utilisez compensate_with() pour annuler les effets secondaires des étapes terminées dans l’ordre inverse.

Utilisez on_cancel() pour un seul mécanisme de nettoyage au niveau du workflow, exécuté à chaque annulation explicite.