task-73: 本地文件作业队列 in-flight 去重和队列背压

This commit is contained in:
2026-08-30 20:22:58 +08:00
parent f190896ea7
commit ec9811c8a5
2 changed files with 233 additions and 2 deletions
@@ -11,6 +11,9 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Service
@RequiredArgsConstructor
@@ -26,6 +29,15 @@ public class TaskFileJobLocalDispatcher {
@Value("${aiimage.result-file-job.local-dispatch-enabled:true}")
private boolean localDispatchEnabled;
/**
* 已受理未完成的 jobId 集合:同 job 重复 dispatch 幂等返回;
* 数量达到上限时拒绝新提交(背压),防止执行队列无界堆积。
*/
@Value("${aiimage.result-file-job.max-inflight-dispatch:64}")
private int maxInflightDispatch = 64;
private final Set<Long> inflightJobIds = ConcurrentHashMap.newKeySet();
public boolean dispatch(Long jobId, Long taskId, String moduleType) {
return dispatch(jobId, taskId, moduleType, false);
}
@@ -39,15 +51,31 @@ public class TaskFileJobLocalDispatcher {
jobId, taskId, moduleType);
return false;
}
int inflightLimit = Math.max(1, maxInflightDispatch);
if (!inflightJobIds.contains(jobId) && inflightJobIds.size() >= inflightLimit) {
log.warn("[task-file-job] local dispatch backpressure, inflight limit reached jobId={} taskId={} moduleType={} inflight={} limit={}",
jobId, taskId, moduleType, inflightJobIds.size(), inflightLimit);
return false;
}
if (!inflightJobIds.add(jobId)) {
log.info("[task-file-job] local dispatch skipped, job already inflight jobId={} taskId={} moduleType={}",
jobId, taskId, moduleType);
return true;
}
try {
taskFileJobDispatchExecutor.execute(() -> processLocally(jobId, taskId, moduleType));
return true;
} catch (RuntimeException ex) {
inflightJobIds.remove(jobId);
log.warn("[task-file-job] local dispatch executor rejected jobId={} taskId={} moduleType={} msg={}",
jobId, taskId, moduleType, ex.getMessage(), ex);
if (force) {
processLocally(jobId, taskId, moduleType);
return true;
try {
processLocally(jobId, taskId, moduleType);
return true;
} finally {
inflightJobIds.remove(jobId);
}
}
return false;
}
@@ -71,6 +99,8 @@ public class TaskFileJobLocalDispatcher {
} catch (Exception ex) {
log.warn("[task-file-job] local dispatch failed jobId={} taskId={} moduleType={} msg={}",
jobId, taskId, moduleType, ex.getMessage(), ex);
} finally {
inflightJobIds.remove(jobId);
}
}
}