Compare commits
No commits in common. "a7a9c10b992bf2b8d3cc8af4a3f9678d48db528e" and "4d5b01f1d3d1171f49f2501cbc076713654ab763" have entirely different histories.
a7a9c10b99
...
4d5b01f1d3
@ -1,6 +1,5 @@
|
|||||||
package com.interplug.qcast.batch;
|
package com.interplug.qcast.batch;
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
@ -11,16 +10,12 @@ import org.springframework.batch.core.explore.JobExplorer;
|
|||||||
import org.springframework.batch.core.launch.JobLauncher;
|
import org.springframework.batch.core.launch.JobLauncher;
|
||||||
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
|
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
|
||||||
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
|
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
|
||||||
import org.springframework.batch.core.repository.JobRepository;
|
|
||||||
import org.springframework.batch.core.repository.JobRestartException;
|
import org.springframework.batch.core.repository.JobRestartException;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.context.event.EventListener;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@ -30,7 +25,6 @@ public class JobLauncherController {
|
|||||||
|
|
||||||
private final JobLauncher jobLauncher;
|
private final JobLauncher jobLauncher;
|
||||||
private final JobExplorer jobExplorer;
|
private final JobExplorer jobExplorer;
|
||||||
private final JobRepository jobRepository; // 생성자 주입을 위해 필드 추가
|
|
||||||
|
|
||||||
@Value("${qsp.master-admin-user-batch-url}")
|
@Value("${qsp.master-admin-user-batch-url}")
|
||||||
private String qspInterfaceUrl;
|
private String qspInterfaceUrl;
|
||||||
@ -38,26 +32,6 @@ public class JobLauncherController {
|
|||||||
@Value("${spring.profiles.scheduler}")
|
@Value("${spring.profiles.scheduler}")
|
||||||
private String scheduler;
|
private String scheduler;
|
||||||
|
|
||||||
/**
|
|
||||||
* 서버 시작 시 실행 중(STARTED)인 상태로 남은 Job들을 FAILED 처리
|
|
||||||
*/
|
|
||||||
@EventListener(ApplicationReadyEvent.class)
|
|
||||||
public void resetFailedJobs() {
|
|
||||||
log.info("Checking for 'STARTED' jobs to reset after reboot...");
|
|
||||||
for (String jobName : jobs.keySet()) {
|
|
||||||
Set<JobExecution> runningExecutions = jobExplorer.findRunningJobExecutions(jobName);
|
|
||||||
for (JobExecution execution : runningExecutions) {
|
|
||||||
execution.setStatus(BatchStatus.FAILED);
|
|
||||||
execution.setExitStatus(ExitStatus.FAILED.addExitDescription("Reset on application startup"));
|
|
||||||
execution.setEndTime(LocalDateTime.now()); // new Date() 대신 LocalDateTime.now() 사용
|
|
||||||
jobRepository.update(execution);
|
|
||||||
log.info("Reset job execution {} for job {}", execution.getId(), jobName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 특정 Job을 매핑으로 실행하는 메소드
|
* 특정 Job을 매핑으로 실행하는 메소드
|
||||||
*
|
*
|
||||||
@ -262,10 +236,7 @@ public class JobLauncherController {
|
|||||||
"specialNoteDispItemAdditionalJob",
|
"specialNoteDispItemAdditionalJob",
|
||||||
"planConfirmJob",
|
"planConfirmJob",
|
||||||
"estimateSyncJob",
|
"estimateSyncJob",
|
||||||
"bomJob",
|
"bomJob"
|
||||||
"storeAdditionalJob",
|
|
||||||
"businessChargerJob",
|
|
||||||
"adminUserJob"
|
|
||||||
));
|
));
|
||||||
|
|
||||||
// 스케줄러가 비활성화되어 있고, 허용된 작업이 아닌 경우
|
// 스케줄러가 비활성화되어 있고, 허용된 작업이 아닌 경우
|
||||||
@ -293,42 +264,19 @@ public class JobLauncherController {
|
|||||||
*/
|
*/
|
||||||
private boolean isJobRunning(String jobName) {
|
private boolean isJobRunning(String jobName) {
|
||||||
try {
|
try {
|
||||||
Set<JobExecution> runningExecutions = jobExplorer.findRunningJobExecutions(jobName);
|
List<JobInstance> jobInstances = jobExplorer.findJobInstancesByJobName(jobName, 0, 1);
|
||||||
if (runningExecutions.isEmpty()) {
|
if (jobInstances.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isActuallyBlocked = false;
|
JobInstance latestJobInstance = jobInstances.get(0);
|
||||||
for (JobExecution execution : runningExecutions) {
|
List<JobExecution> jobExecutions = jobExplorer.getJobExecutions(latestJobInstance);
|
||||||
LocalDateTime startTime = execution.getStartTime();
|
|
||||||
if (startTime == null) continue;
|
|
||||||
|
|
||||||
// 현재 시간과 시작 시간의 차이 계산
|
return jobExecutions.stream()
|
||||||
Duration duration = Duration.between(startTime, LocalDateTime.now());
|
.anyMatch(execution -> execution.getStatus() == BatchStatus.STARTED
|
||||||
long hours = duration.toHours();
|
|| execution.getStatus() == BatchStatus.STARTING);
|
||||||
|
|
||||||
if (hours >= 1) {
|
|
||||||
// 1시간 이상 경과한 경우 로그 출력 및 DB 강제 업데이트
|
|
||||||
log.warn("Job {} (Execution ID: {}) 가 실행된 지 {}시간이 지났습니다. 상태를 FAILED로 초기화하고 재실행을 시도합니다.",
|
|
||||||
jobName, execution.getId(), hours);
|
|
||||||
|
|
||||||
execution.setStatus(BatchStatus.FAILED);
|
|
||||||
execution.setExitStatus(ExitStatus.FAILED.addExitDescription("Forcefully reset: Running for more than 1 hour"));
|
|
||||||
execution.setEndTime(LocalDateTime.now());
|
|
||||||
jobRepository.update(execution);
|
|
||||||
|
|
||||||
log.info("Job {} 의 이전 실행 상태가 성공적으로 초기화되었습니다.", jobName);
|
|
||||||
} else {
|
|
||||||
// 1시간 미만으로 실행 중인 잡이 있다면 진짜 실행 중인 것으로 간주
|
|
||||||
log.info("Job {} 가 현재 실행 중입니다. (시작 시간: {}, 경과 시간: {}분)",
|
|
||||||
jobName, startTime, duration.toMinutes());
|
|
||||||
isActuallyBlocked = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return isActuallyBlocked;
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Job 상태 확인 중 오류 발생: {}", e.getMessage());
|
log.error("Error checking job running status: {}", e.getMessage());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user