5 changed files with 379 additions and 72 deletions
@ -0,0 +1,113 @@ |
|||
package com.zdxt.enforcementcode.businessdatasyn.executor; |
|||
|
|||
import lombok.Data; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.time.LocalDateTime; |
|||
import java.time.ZoneId; |
|||
import java.util.Map; |
|||
import java.util.UUID; |
|||
import java.util.concurrent.ConcurrentHashMap; |
|||
|
|||
/** |
|||
* 同步任务运行状态持有器 |
|||
* <p>基于内存 ConcurrentHashMap,用于前端轮询判断异步任务是否完成</p> |
|||
* <p>注意:仅供 UI 触发的同步任务使用;Quartz Job 和单元测试直接调 scheduler,不经过本类</p> |
|||
* <p>单节点部署有效,多节点部署需改为 Redis</p> |
|||
* |
|||
* @author zrb |
|||
*/ |
|||
@Slf4j |
|||
@Component |
|||
public class SyncJobStatusHolder { |
|||
|
|||
/** 任务过期时间(毫秒),完成后 30 分钟自动清理 */ |
|||
private static final long EXPIRE_MS = 30 * 60 * 1000L; |
|||
|
|||
private final Map<String, JobStatus> jobs = new ConcurrentHashMap<>(); |
|||
|
|||
/** |
|||
* 创建一个新任务,返回 jobId |
|||
*/ |
|||
public String createJob(String jobType, String configKey) { |
|||
String jobId = UUID.randomUUID().toString().replace("-", ""); |
|||
JobStatus status = new JobStatus(); |
|||
status.setJobId(jobId); |
|||
status.setJobType(jobType); |
|||
status.setConfigKey(configKey); |
|||
status.setStatus("RUNNING"); |
|||
status.setStartTime(LocalDateTime.now()); |
|||
jobs.put(jobId, status); |
|||
log.info("[BizSync-Job] 创建任务: jobId={}, type={}, configKey={}", jobId, jobType, configKey); |
|||
cleanExpired(); |
|||
return jobId; |
|||
} |
|||
|
|||
/** |
|||
* 标记任务成功 |
|||
*/ |
|||
public void markSuccess(String jobId, String message) { |
|||
JobStatus status = jobs.get(jobId); |
|||
if (status != null) { |
|||
status.setStatus("SUCCESS"); |
|||
status.setEndTime(LocalDateTime.now()); |
|||
status.setMessage(message); |
|||
log.info("[BizSync-Job] 任务成功: jobId={}, msg={}", jobId, message); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 标记任务失败 |
|||
*/ |
|||
public void markFail(String jobId, String errorMsg) { |
|||
JobStatus status = jobs.get(jobId); |
|||
if (status != null) { |
|||
status.setStatus("FAIL"); |
|||
status.setEndTime(LocalDateTime.now()); |
|||
status.setMessage(errorMsg); |
|||
log.error("[BizSync-Job] 任务失败: jobId={}, err={}", jobId, errorMsg); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 获取任务状态 |
|||
*/ |
|||
public JobStatus getJob(String jobId) { |
|||
return jobs.get(jobId); |
|||
} |
|||
|
|||
/** |
|||
* 清理过期任务(完成时间超过 EXPIRE_MS 的) |
|||
*/ |
|||
private void cleanExpired() { |
|||
long now = System.currentTimeMillis(); |
|||
jobs.entrySet().removeIf(entry -> { |
|||
JobStatus s = entry.getValue(); |
|||
if (s.getEndTime() == null) return false; |
|||
long endMillis = s.getEndTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); |
|||
return (now - endMillis) > EXPIRE_MS; |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* 任务状态 DTO |
|||
*/ |
|||
@Data |
|||
public static class JobStatus { |
|||
/** 任务 UUID */ |
|||
private String jobId; |
|||
/** 任务类型: TRIGGER_ONE / TRIGGER_ALL / TRIGGER_FORCE */ |
|||
private String jobType; |
|||
/** 关联配置 key(TRIGGER_ONE 时有值) */ |
|||
private String configKey; |
|||
/** 状态: RUNNING / SUCCESS / FAIL */ |
|||
private String status; |
|||
/** 提示信息 */ |
|||
private String message; |
|||
/** 开始时间 */ |
|||
private LocalDateTime startTime; |
|||
/** 结束时间 */ |
|||
private LocalDateTime endTime; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue