5.8 KiB
5.8 KiB
部署记录状态:CANCELLED vs REJECTED 分析
当前状态
CANCELLED(已取消)的使用场景
唯一使用场景:审批被拒绝
- 位置:
DeployRecordServiceImpl.updateStatusFromApproval() - 代码:
record.setStatus(DeployRecordStatusEnums.CANCELLED); - 日志:
"部署记录状态已更新为已取消(审批被拒)"
结论:当前 CANCELLED 只用于审批被拒绝的场景。
其他状态的使用场景
| 状态 | 使用场景 | 来源 |
|---|---|---|
| TERMINATED | 工作流被手动终止 | 工作流状态 TERMINATED |
| FAILED | 工作流执行失败 | 工作流状态 FAILED |
| CANCELLED | 审批被拒绝 | 审批事件 ApprovalResultEnum.REJECTED |
问题分析
问题1:语义不清晰
当前问题:
CANCELLED(已取消)语义模糊,不能明确表示是"审批被拒绝"- 未来如果有手动取消部署功能,会产生歧义
对比:
- 工作流层面:
ApprovalResultEnum.REJECTED(拒绝) - 部署记录层面:
CANCELLED(已取消) - 不一致:两个层面使用不同的语义
问题2:未来扩展性
未来可能的场景:
- 手动取消部署:用户主动取消正在运行的部署
- 应该使用什么状态?如果用
CANCELLED,会与"审批被拒绝"混淆
- 应该使用什么状态?如果用
- 超时自动取消:部署超时自动取消
- 应该使用什么状态?
方案对比
方案A:保留 CANCELLED,新增 REJECTED(推荐)
状态定义:
public enum DeployRecordStatusEnums {
// ... 其他状态 ...
/**
* 审批被拒绝(终态)
*/
REJECTED("REJECTED", "审批被拒绝"),
/**
* 已取消(终态)
* 用于:手动取消部署、超时自动取消等场景
*/
CANCELLED("CANCELLED", "已取消"),
// ... 其他状态 ...
}
优点:
- ✅ 语义清晰:
REJECTED明确表示"审批被拒绝" - ✅ 与工作流层面保持一致:
ApprovalResultEnum.REJECTED→DeployRecordStatusEnums.REJECTED - ✅ 保留扩展性:
CANCELLED可用于未来手动取消场景 - ✅ 状态语义明确,便于理解和维护
缺点:
- 需要新增枚举值
- 需要修改相关代码
- 需要数据库迁移(如果已有数据)
需要修改的地方:
- 枚举类:新增
REJECTED DeployRecordServiceImpl.updateStatusFromApproval():改为REJECTEDisFinalState():添加REJECTED- 统计查询:
REJECTED计入失败计数 fromWorkflowStatus():不需要修改(因为REJECTED不是从工作流状态转换来的)
方案B:直接用 REJECTED 替代 CANCELLED
状态定义:
public enum DeployRecordStatusEnums {
// ... 其他状态 ...
/**
* 审批被拒绝(终态)
*/
REJECTED("REJECTED", "审批被拒绝"),
// 删除 CANCELLED
}
优点:
- ✅ 语义清晰
- ✅ 与工作流层面保持一致
- ✅ 简化状态模型
缺点:
- ❌ 失去扩展性:如果未来需要手动取消功能,需要再添加状态
- ❌ 如果未来需要区分"审批被拒绝"和"手动取消",需要再次修改
方案C:保持现状(不推荐)
优点:
- 无需修改代码
缺点:
- ❌ 语义不清晰
- ❌ 与工作流层面不一致
- ❌ 未来扩展困难
推荐方案
推荐采用方案A:保留 CANCELLED,新增 REJECTED
理由
-
语义清晰:
REJECTED:明确表示"审批被拒绝"CANCELLED:用于"手动取消"等场景
-
状态映射清晰:
审批层面:ApprovalResultEnum.REJECTED ↓ 部署记录:DeployRecordStatusEnums.REJECTED -
未来扩展性:
- 如果未来需要手动取消部署功能,可以直接使用
CANCELLED - 如果不需要手动取消,
CANCELLED可以保留但不用
- 如果未来需要手动取消部署功能,可以直接使用
-
状态完整性:
- 终态包括:
SUCCESS、FAILED、REJECTED、CANCELLED、TERMINATED、PARTIAL_SUCCESS - 语义清晰,便于理解和维护
- 终态包括:
实施建议
步骤1:新增 REJECTED 枚举
/**
* 审批被拒绝(终态)
*/
REJECTED("REJECTED", "审批被拒绝"),
步骤2:修改审批状态更新逻辑
} else {
// 审批被拒绝,更新为审批被拒绝
record.setStatus(DeployRecordStatusEnums.REJECTED);
log.info("部署记录状态已更新为审批被拒绝: id={}, workflowInstanceId={}",
record.getId(), workflowInstanceId);
}
步骤3:更新终态判断
private boolean isFinalState(DeployRecordStatusEnums status) {
return status == DeployRecordStatusEnums.SUCCESS
|| status == DeployRecordStatusEnums.FAILED
|| status == DeployRecordStatusEnums.REJECTED // 新增
|| status == DeployRecordStatusEnums.CANCELLED
|| status == DeployRecordStatusEnums.TERMINATED
|| status == DeployRecordStatusEnums.PARTIAL_SUCCESS;
}
步骤4:更新统计查询
-- 在统计查询中,REJECTED 计入失败
SUM(CASE WHEN dr.status IN ('FAILED', 'REJECTED', 'CANCELLED', 'TERMINATED', 'PARTIAL_SUCCESS')
OR (dr.status = 'CREATED' AND TIMESTAMPDIFF(MINUTE, dr.create_time, NOW()) > 30)
THEN 1 ELSE 0 END) as failedCount
步骤5:数据库迁移(可选)
如果已有审批被拒绝的记录,状态为 CANCELLED,可以考虑:
- 保留现有数据(
CANCELLED继续表示审批被拒绝) - 或者迁移数据(将
CANCELLED迁移为REJECTED)
结论
推荐新增 REJECTED 状态,用于明确表示"审批被拒绝",与工作流层面的 ApprovalResultEnum.REJECTED 保持一致。
保留 CANCELLED 状态,用于未来可能的手动取消部署功能。
这样既保证了语义清晰,又保留了扩展性。