工作流取消
可以通过编程方式或经由 CLI 取消工作流。工作流取消后,Queuety 会将其状态设为 cancelled,将所有待处理或正在处理的任务移入封存,并运行可选的清理处理程序。
注册清理处理程序
在工作流构建器上使用 on_cancel() 注册一个在工作流取消时运行的类。处理程序类必须实现 handle( array $state ): void 方法。
PHP
use Queuety\Queuety;
Queuety::workflow( 'import_data' )
->then( FetchDataHandler::class )
->then( TransformDataHandler::class )
->then( LoadDataHandler::class )
->on_cancel( ImportCleanupHandler::class )
->dispatch( [ 'source_url' => $url ] );
清理处理程序会接收公开的工作流状态(所有名称不以 _ 开头的键):
PHP
class ImportCleanupHandler {
public function handle( array $state ): void {
// Clean up any partial imports.
if ( isset( $state['temp_table'] ) ) {
global $wpdb;
$wpdb->query( "DROP TABLE IF EXISTS {$state['temp_table']}" );
}
// Notify the user.
wp_mail(
$state['notify_email'] ?? '',
'Import cancelled',
'Your data import was cancelled.'
);
}
}
通过 PHP 取消
使用工作流 ID 调用 Queuety::cancel_workflow():
PHP
Queuety::cancel_workflow( $workflow_id );
此方法会:
- 锁定工作流行
- 将工作流状态设为
cancelled - 将该工作流的所有待处理和正在处理的任务移入封存,并附上消息 "Workflow cancelled"
- 记录
workflow_cancelled事件并提交 - 按相反顺序运行已完成步骤的补偿处理程序(如果通过
compensate_with()注册过) - 运行
on_cancel清理处理程序(如果已注册)
如果工作流已处于 completed 或 cancelled 状态,就会抛出 RuntimeException。
通过 CLI 取消
命令行
wp queuety workflow cancel <id>
| 选项 | 说明 |
|---|---|
<id> |
要取消的工作流 ID(必填) |
命令行
wp queuety workflow cancel 42
取消时会发生什么
工作流取消时:
- 状态 更改为
cancelled - 步骤补偿处理程序 按完成顺序的逆序运行(如果你通过
compensate_with()添加了它们) - 清理处理程序 在工作流行标记为
cancelled后运行 - 该工作流的 待处理任务 会立即移入封存
- 该工作流的 正在处理的任务 会移入封存;正在执行的处理程序完成后,其输出会被丢弃,工作流也不会继续推进
- 先前步骤的 已完成任务 保持原样
- 记录包含事件
workflow_cancelled的 日志条目
已取消与失败
| 方面 | 失败 | 已取消 |
|---|---|---|
| 触发条件 | 某个步骤耗尽重试次数 | 显式调用 cancel_workflow() |
| 状态 | failed |
cancelled |
| 能否重试 | 可以,通过 retry_workflow() 重试,除非工作流已经完成补偿 |
不可以 |
| 清理处理程序 | 不会调用 | 如果通过 on_cancel() 注册,则会调用 |
| 日志事件 | workflow_failed |
workflow_cancelled |
示例:取消前进行确认
一种常见模式是在取消前检查工作流状态:
PHP
$status = Queuety::workflow_status( $workflow_id );
if ( null === $status ) {
throw new \RuntimeException( 'Workflow not found.' );
}
if ( 'running' === $status->status->value || 'paused' === $status->status->value ) {
Queuety::cancel_workflow( $workflow_id );
}