工作流补偿
补偿机制允许你为已完成的工作流步骤添加回滚处理程序。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 会运行:
CancelSubscriptionCompensationDeleteRemoteUserCompensation
补偿处理程序
补偿处理程序实现 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() 添加一个工作流级清理钩子,使其在工作流被显式取消时运行。