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:
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:
CancelSubscriptionCompensationDeleteRemoteUserCompensation
Controladores de compensación
Los controladores de compensación implementan Contracts\Compensation:
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:
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.