Компенсация workflow
Компенсация позволяет назначить обработчик отката для завершенного шага workflow. Queuety сохраняет снимок публичного состояния после завершения этого шага, а затем запускает обработчики компенсации в обратном порядке, когда workflow отменяют или, по желанию, при его сбое.
Метод compensate_with()
Вызовите compensate_with() сразу после шага, который он должен отменить:
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 ] );
Если позже workflow отменят, будет запущен Queuety:
CancelSubscriptionCompensationDeleteRemoteUserCompensation
Обработчики компенсации
Обработчики компенсации реализуют 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'] );
}
}
Обработчик получает публичное состояние workflow в том виде, в каком оно было сразу после завершения компенсируемого шага. Зарезервированные внутренние ключи не включаются.
Отмена и сбой
При явной отмене компенсации завершенных шагов всегда запускаются перед необязательным обработчиком on_cancel().
При сбое компенсации запускаются только по вашему выбору:
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() в завершенной истории workflow после сбоя остаются все шаги, и его можно повторить с шага, на котором произошел сбой.
С compensate_on_failure() компенсации завершенных шагов запускаются после того, как workflow отмечен как завершившийся сбоем. После этого вызов retry_workflow() выбрасывает исключение, поскольку компенсация workflow уже выполнена.
Поддерживаемые типы шагов
Компенсацию можно назначить для:
- последовательных шагов
then() - групп
parallel() - шагов
for_each() - шагов
run_workflow() - шагов задержки
delay() - шагов ожидания сигнала
wait_for_signal() - шагов зависимости workflow
wait_for_workflow()
Для run_workflow() и for_each() снимок для компенсации записывается после полного завершения вложенной или разветвленной работы.
on_cancel() и компенсация
Используйте compensate_with(), чтобы отменять побочные эффекты завершенных шагов в обратном порядке.
Используйте on_cancel() для одной точки очистки на уровне workflow, которая должна запускаться при каждой явной отмене workflow.