본문으로 건너뛰기

워크플로 보상

보상을 사용하면 완료된 워크플로 단계에 롤백 핸들러를 연결할 수 있습니다. Queuety은 단계가 끝날 때 공개 상태의 스냅샷을 저장한 다음, 워크플로가 취소되거나 선택적으로 실패할 때 보상 핸들러를 역순으로 실행합니다.

compensate_with() 메서드

되돌려야 할 단계 바로 뒤에 compensate_with()을 호출하세요:

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

나중에 워크플로가 취소되면 Queuety이 실행됩니다:

  1. CancelSubscriptionCompensation
  2. DeleteRemoteUserCompensation

보상 핸들러

보상 핸들러는 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'] );
    }
}

핸들러는 보상 대상 단계가 완료된 직후의 공개 워크플로 상태를 받습니다. 예약된 내부 키는 포함되지 않습니다.

취소와 실패 비교

명시적으로 취소하면 완료된 단계의 보상이 선택적 on_cancel() 핸들러보다 항상 먼저 실행됩니다.

실패 시 보상은 선택적으로 활성화한 경우에만 실행됩니다:

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

compensate_on_failure()이 없으면 실패한 워크플로는 완료된 단계의 기록을 그대로 유지하며 실패한 단계부터 재시도할 수 있습니다.

compensate_on_failure()을 사용하면 워크플로가 실패로 표시된 후 완료된 단계의 보상이 실행됩니다. 이후 워크플로가 이미 보상되었으므로 retry_workflow()이 예외를 발생시킵니다.

지원되는 단계 유형

다음 항목에 보상을 연결할 수 있습니다:

  • 순차 then() 단계
  • parallel() 그룹
  • for_each() 단계
  • run_workflow() 단계
  • delay() 지연 단계
  • wait_for_signal() 신호 단계
  • wait_for_workflow() 워크플로 종속성 단계

run_workflow()과 for_each()의 경우 중첩 작업이나 분기 작업이 모두 끝난 후 보상 스냅샷이 기록됩니다.

on_cancel()과 보상의 차이

완료된 단계의 부수 효과를 역순으로 되돌리려면 compensate_with()을 사용하세요.

워크플로가 명시적으로 취소될 때마다 실행해야 하는 워크플로 수준의 정리 후크 하나를 설정하려면 on_cancel()을 사용하세요.