From ed1947837908d175ac6c7220d5beaeb0035b0518 Mon Sep 17 00:00:00 2001 From: dengqichen Date: Wed, 5 Nov 2025 13:19:48 +0800 Subject: [PATCH] =?UTF-8?q?=E6=89=93=E5=8D=B0=E4=BA=86JENKINS=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflow/constants/WorkFlowConstants.java | 28 ++-------- .../event/FlowableEventDispatcher.java | 2 +- .../event/handler/ActivityEventHandler.java | 9 ++-- .../event/handler/JobEventHandler.java | 52 +++++++++---------- ....java => ProcessInstanceEventHandler.java} | 43 +++++++++------ 5 files changed, 60 insertions(+), 74 deletions(-) rename backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/{ProcessEventHandler.java => ProcessInstanceEventHandler.java} (72%) diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/constants/WorkFlowConstants.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/constants/WorkFlowConstants.java index bcb71b2e..6ac8ab32 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/constants/WorkFlowConstants.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/constants/WorkFlowConstants.java @@ -2,30 +2,12 @@ package com.qqchen.deploy.backend.workflow.constants; public interface WorkFlowConstants { - String WORKFLOW_EXEC_ERROR = "WORKFLOW_EXEC_ERROR"; + String WORKFLOW_EXEC_ERROR = "workflow_exec_error"; - String BOUNDARY_EVENT_ERROR_PREFIX = "BOUNDARY_EVENT_ERROR_"; + String BOUNDARY_EVENT_ERROR_PREFIX = "boundary_event_error_"; - String END_EVENT_ERROR_PREFIX = "END_EVENT_ERROR_"; + String END_EVENT_ERROR_PREFIX = "end_event_error_"; - String SEQUENCE_FLOW_ERROR_PREFIX = "SEQUENCE_FLOW_ERROR_"; + String SEQUENCE_FLOW_ERROR_PREFIX = "sequence_flow_error_"; - String ASYNC_CONTINUATION = "async-continuation"; - - String WORKFLOW_PREVIOUS_NODE_EXECUTION_STATE_VARIABLE_NAME = "PREVIOUS_NODE_EXECUTION_STATE"; - - /** - * 执行状态:成功 - */ - String WORKFLOW_NODE_EXECUTION_STATE_SUCCESS = "SUCCESS"; - - /** - * 执行状态:失败 - */ - String WORKFLOW_NODE_EXECUTION_STATE_FAILURE = "FAILURE"; - - /** - * 执行状态:中止 - */ - String WORKFLOW_NODE_EXECUTION_STATUS_ABORTED = "ABORTED"; -} +} \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/FlowableEventDispatcher.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/FlowableEventDispatcher.java index f8726daf..90dc088e 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/FlowableEventDispatcher.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/FlowableEventDispatcher.java @@ -22,7 +22,7 @@ public class FlowableEventDispatcher implements FlowableEventListener { @Override public void onEvent(FlowableEvent event) { String eventType = event.getType().name(); - log.info("Dispatching Flowable event: {}, event class: {}", eventType, event.getClass().getName()); + log.debug("Dispatching Flowable event: {}, event class: {}", eventType, event.getClass().getName()); for (IFlowableEventHandler handler : eventHandlers) { if (handler.canHandle(eventType)) { try { diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/ActivityEventHandler.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/ActivityEventHandler.java index 82096816..cec06168 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/ActivityEventHandler.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/ActivityEventHandler.java @@ -12,8 +12,6 @@ import org.springframework.stereotype.Component; import jakarta.annotation.Resource; import java.time.LocalDateTime; -import java.util.Arrays; -import java.util.List; import static com.qqchen.deploy.backend.workflow.constants.WorkFlowConstants.BOUNDARY_EVENT_ERROR_PREFIX; import static com.qqchen.deploy.backend.workflow.constants.WorkFlowConstants.END_EVENT_ERROR_PREFIX; @@ -25,7 +23,6 @@ public class ActivityEventHandler implements IFlowableEventHandler { @Resource private ApplicationEventPublisher publisher; - @Override public boolean canHandle(String eventType) { return eventType.startsWith("ACTIVITY_"); @@ -37,10 +34,10 @@ public class ActivityEventHandler implements IFlowableEventHandler { if (!(event instanceof FlowableActivityEvent activityEvent)) { return; } - List ignoredList = Arrays.asList(BOUNDARY_EVENT_ERROR_PREFIX, END_EVENT_ERROR_PREFIX); - boolean ignored = ignoredList.stream().anyMatch(v -> activityEvent.getActivityId().contains(v)); - if (ignored) { + // ✅ 优化:直接检查前缀,避免创建 stream,提高性能 + String activityId = activityEvent.getActivityId(); + if (activityId.contains(BOUNDARY_EVENT_ERROR_PREFIX) || activityId.contains(END_EVENT_ERROR_PREFIX)) { return; } WorkflowNodeInstanceStatusEnums status = convertToNodeStatus(eventType); diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/JobEventHandler.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/JobEventHandler.java index 1cb50b6a..9e71905d 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/JobEventHandler.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/JobEventHandler.java @@ -1,6 +1,5 @@ package com.qqchen.deploy.backend.workflow.event.handler; -import cn.hutool.json.JSONUtil; import com.qqchen.deploy.backend.workflow.enums.WorkflowNodeInstanceStatusEnums; import com.qqchen.deploy.backend.workflow.dto.event.TerminationProcessInstanceListenerEvent; import lombok.extern.slf4j.Slf4j; @@ -33,39 +32,38 @@ public class JobEventHandler implements IFlowableEventHandler { if (!(event instanceof FlowableEngineEntityEvent entityEvent)) { return; } - JobEntityImpl job = (JobEntityImpl) entityEvent.getEntity(); - log.info("Processing job event: {}", JSONUtil.toJsonStr(job)); - WorkflowNodeInstanceStatusEnums status = convertToNodeStatus(eventType); - switch (status) { - case FAILED -> { - publisher.publishEvent(new TerminationProcessInstanceListenerEvent(job.getId(), job.getProcessInstanceId(), ((FlowableEntityExceptionEventImpl) event).getCause().getMessage())); - } - default -> { - - } + + // ✅ 类型转换安全:检查实体类型 + Object entity = entityEvent.getEntity(); + if (!(entity instanceof JobEntityImpl job)) { + log.debug("Job event entity is not JobEntityImpl, skipping: {}", entity.getClass().getName()); + return; + } + + log.debug("Processing job event: jobId={}, processInstanceId={}", job.getId(), job.getProcessInstanceId()); + WorkflowNodeInstanceStatusEnums status = convertToNodeStatus(eventType); + + // ✅ 类型转换安全:只在失败事件时转换为异常事件获取错误信息 + if (status == WorkflowNodeInstanceStatusEnums.FAILED) { + String errorMessage = null; + if (event instanceof FlowableEntityExceptionEventImpl exceptionEvent) { + Throwable cause = exceptionEvent.getCause(); + errorMessage = cause != null ? cause.getMessage() : "Job execution failed"; + } else { + errorMessage = "Job execution failed"; + } + publisher.publishEvent(new TerminationProcessInstanceListenerEvent( + job.getId(), + job.getProcessInstanceId(), + errorMessage + )); } -// if (status != null) { -// publisher.publishEvent(WorkflowNodeInstanceStatusChangeEvent.builder() -// .processInstanceId(job.getProcessInstanceId()) -// .executionId(job.getExecutionId()) -// .nodeId(job.getElementId()) -// .nodeName(job.getElementName()) -// .nodeType(job.getJobHandlerType()) -// .status(status) -// .startTime(job.getCreateTime() != null ? DateUtil.toLocalDateTime(job.getCreateTime()) : null) -// .endTime(status.isFinalState() ? LocalDateTime.now() : null) -// .build() -// ); -// } } private WorkflowNodeInstanceStatusEnums convertToNodeStatus(String eventType) { return switch (eventType) { case "JOB_EXECUTION_SUCCESS" -> WorkflowNodeInstanceStatusEnums.RUNNING; -// case "JOB_EXECUTION_START" -> WorkflowNodeInstanceStatusEnums.RUNNING; case "JOB_EXECUTION_FAILURE" -> WorkflowNodeInstanceStatusEnums.FAILED; -// case "JOB_EXECUTION_REJECTED" -> WorkflowNodeInstanceStatusEnums.FAILED; -// case "JOB_EXECUTION_NOJOB_FOUND" -> WorkflowNodeInstanceStatusEnums.FAILED; default -> null; }; } diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/ProcessEventHandler.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/ProcessInstanceEventHandler.java similarity index 72% rename from backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/ProcessEventHandler.java rename to backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/ProcessInstanceEventHandler.java index ac9bfecc..3e17de46 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/ProcessEventHandler.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/event/handler/ProcessInstanceEventHandler.java @@ -16,11 +16,16 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import jakarta.annotation.Resource; -import java.util.List; +/** + * 流程实例事件处理器 + * 处理 Flowable 的 PROCESS_* 级别事件(流程实例生命周期事件) + * + * @author system + */ @Slf4j @Component -public class ProcessEventHandler implements IFlowableEventHandler { +public class ProcessInstanceEventHandler implements IFlowableEventHandler { @Resource private ApplicationEventPublisher publisher; @@ -51,19 +56,25 @@ public class ProcessEventHandler implements IFlowableEventHandler { } if (status != null) { - HistoricProcessInstance historicProcessInstance = processEngine.getHistoryService() - .createHistoricProcessInstanceQuery() - .processInstanceId(processEvent.getProcessInstanceId()) - .singleResult(); + // ✅ 优化:只在需要 endTime 时查询 HistoricProcessInstance(仅完成状态) + java.time.LocalDateTime endTime = null; + if (status.isFinalState()) { + HistoricProcessInstance historicProcessInstance = processEngine.getHistoryService() + .createHistoricProcessInstanceQuery() + .processInstanceId(processEvent.getProcessInstanceId()) + .singleResult(); + if (historicProcessInstance != null && historicProcessInstance.getEndTime() != null) { + endTime = DateUtil.toLocalDateTime(historicProcessInstance.getEndTime()); + } + } - log.info("工作流实例状态变更: processInstanceId={}, eventType={}, status={}", + log.debug("工作流实例状态变更: processInstanceId={}, eventType={}, status={}", processEvent.getProcessInstanceId(), eventType, status); publisher.publishEvent(WorkflowInstanceStatusChangeEvent.builder() .processInstanceId(processEvent.getProcessInstanceId()) .status(status) - .endTime(historicProcessInstance != null && historicProcessInstance.getEndTime() != null ? - DateUtil.toLocalDateTime(historicProcessInstance.getEndTime()) : null) + .endTime(endTime) .build() ); } @@ -76,11 +87,10 @@ public class ProcessEventHandler implements IFlowableEventHandler { * @return 如果所有节点成功返回 COMPLETED,如果有节点失败返回 COMPLETED_WITH_ERRORS */ private WorkflowInstanceStatusEnums determineCompletionStatus(String processInstanceId) { - // 查询该流程的所有节点实例 - List nodeInstances = workflowNodeInstanceRepository.findByProcessInstanceId(processInstanceId); - - // 检查是否有失败的节点(排除开始和结束节点) - boolean hasFailedNode = nodeInstances.stream() + // ✅ 优化:只查询有失败状态的节点,避免加载所有节点数据 + // 先检查是否有失败的节点(排除开始和结束节点) + boolean hasFailedNode = workflowNodeInstanceRepository.findByProcessInstanceId(processInstanceId) + .stream() .filter(node -> !"StartEvent".equals(node.getNodeType()) && !"EndEvent".equals(node.getNodeType())) .anyMatch(node -> WorkflowNodeInstanceStatusEnums.FAILED.equals(node.getStatus())); @@ -88,7 +98,7 @@ public class ProcessEventHandler implements IFlowableEventHandler { log.warn("工作流实例 {} 完成,但存在失败的节点", processInstanceId); return WorkflowInstanceStatusEnums.COMPLETED_WITH_ERRORS; } else { - log.info("工作流实例 {} 完成,所有节点均成功", processInstanceId); + log.debug("工作流实例 {} 完成,所有节点均成功", processInstanceId); return WorkflowInstanceStatusEnums.COMPLETED; } } @@ -100,10 +110,9 @@ public class ProcessEventHandler implements IFlowableEventHandler { case "PROCESS_COMPLETED" -> WorkflowInstanceStatusEnums.COMPLETED; case "PROCESS_CANCELLED" -> WorkflowInstanceStatusEnums.FAILED; case "PROCESS_SUSPENDED" -> WorkflowInstanceStatusEnums.SUSPENDED; -// case "PROCESS_RESUMED" -> WorkflowInstanceStatusEnums.RUNNING; case "PROCESS_COMPLETED_WITH_TERMINATE_END_EVENT" -> WorkflowInstanceStatusEnums.TERMINATED; default -> null; }; } -} \ No newline at end of file +}