Pular para o conteúdo

Compensação do workflow

A compensação permite associar um handler de reversão a uma etapa concluída do workflow. Queuety armazena um snapshot do estado público quando a etapa termina e, em seguida, executa os handlers de compensação em ordem inversa quando o workflow é cancelado ou, opcionalmente, quando falha.

O método compensate_with()

Chame compensate_with() imediatamente após a etapa que ele deve desfazer:

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

Se o workflow for cancelado posteriormente, Queuety será executado:

  1. CancelSubscriptionCompensation
  2. DeleteRemoteUserCompensation

Handlers de compensação

Os handlers de compensação implementam 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'] );
    }
}

O handler recebe o estado público do workflow tal como estava imediatamente após a conclusão da etapa compensada. As chaves internas reservadas não são incluídas.

Cancelamento vs. falha

Em caso de cancelamento explícito, as compensações das etapas concluídas são sempre executadas antes do handler opcional on_cancel().

Em caso de falha, as compensações só são executadas se você optar por isso:

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

Sem compensate_on_failure(), um workflow com falha mantém intacto o histórico das etapas concluídas e pode ser repetido a partir da etapa com falha.

Com compensate_on_failure(), as compensações das etapas concluídas são executadas depois que o workflow é marcado como com falha. Depois disso, retry_workflow() lança uma exceção porque o workflow já foi compensado.

Tipos de etapa compatíveis

É possível associar uma compensação a:

  • etapas sequenciais then()
  • grupos parallel()
  • etapas for_each()
  • etapas run_workflow()
  • etapas de atraso delay()
  • etapas de sinal wait_for_signal()
  • etapas de dependência de workflow wait_for_workflow()

Para run_workflow() e for_each(), o snapshot da compensação é registrado depois que o trabalho aninhado ou ramificado é totalmente concluído.

on_cancel() vs. compensação

Use compensate_with() para desfazer efeitos colaterais de etapas concluídas em ordem inversa.

Use on_cancel() para um único hook de limpeza no nível do workflow que deve ser executado sempre que o workflow for cancelado explicitamente.