Saltar al contenido

Compensación de flujos de trabajo

La compensación permite asociar un controlador de reversión a un paso completado del flujo de trabajo. Queuety guarda una instantánea del estado público cuando termina ese paso y luego ejecuta los controladores de compensación en orden inverso cuando se cancela el flujo de trabajo o, de forma opcional, cuando falla.

El método compensate_with()

Llame a compensate_with() inmediatamente después del paso que debe deshacer:

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 más adelante se cancela el flujo de trabajo, se ejecuta Queuety:

  1. CancelSubscriptionCompensation
  2. DeleteRemoteUserCompensation

Controladores de compensación

Los controladores de compensación implementan 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'] );
    }
}

El controlador recibe el estado público del flujo de trabajo tal como estaba inmediatamente después de completarse el paso compensado. No se incluyen las claves internas reservadas.

Cancelación frente a fallo

En caso de cancelación explícita, las compensaciones de los pasos completados siempre se ejecutan antes del controlador opcional on_cancel().

En caso de fallo, las compensaciones solo se ejecutan si se habilitan expresamente:

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

Sin compensate_on_failure(), un flujo de trabajo fallido conserva intacto el historial de pasos completados y se puede reintentar desde el paso fallido.

Con compensate_on_failure(), las compensaciones de los pasos completados se ejecutan después de marcar el flujo de trabajo como fallido. Después, retry_workflow() genera una excepción porque el flujo de trabajo ya se ha compensado.

Tipos de pasos admitidos

Se puede asociar la compensación a:

  • pasos secuenciales de then()
  • grupos de parallel()
  • pasos de for_each()
  • pasos de run_workflow()
  • pasos de retardo de delay()
  • pasos de señal de wait_for_signal()
  • pasos de dependencia de flujo de trabajo de wait_for_workflow()

Para run_workflow() y for_each(), la instantánea de compensación se registra cuando todo el trabajo anidado o ramificado ha terminado por completo.

on_cancel() frente a compensación

Use compensate_with() para deshacer los efectos secundarios de los pasos completados en orden inverso.

Use on_cancel() para un único enlace de limpieza a nivel del flujo de trabajo que deba ejecutarse cada vez que se cancele explícitamente el flujo.