de.otto.edison.jobs.repository.cleanup.KeepLastJobs Maven / Gradle / Ivy
Show all versions of edison-jobs Show documentation
package de.otto.edison.jobs.repository.cleanup;
import de.otto.edison.jobs.domain.JobInfo;
import de.otto.edison.jobs.repository.JobRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import static de.otto.edison.jobs.domain.JobInfo.JobStatus.OK;
import static java.util.Comparator.comparing;
import static java.util.Comparator.reverseOrder;
import static java.util.stream.Collectors.groupingBy;
/**
* A JobCleanupStrategy that is removing all but the newest N jobs of each type.
*
* Concurrent executions of the strategy may have the effect, that more JobInfos than expected are deleted! This
* may happen, if multiple instances of your application are running in parallel.
*
* @author Guido Steinacker
* @since 26.02.15
*/
public class KeepLastJobs implements JobCleanupStrategy {
private static final Logger LOG = LoggerFactory.getLogger(KeepLastJobs.class);
private static final long KEEP_LAST_JOBS_CLEANUP_INTERVAL = 10L * 60L * 1000L;
private final int numberOfJobsToKeep;
private JobRepository jobRepository;
/**
* @param jobRepository the JobRepository instance used to fetch job infos
* @param numberOfJobsToKeep the number of jobs that are kept
*/
public KeepLastJobs(final JobRepository jobRepository, final int numberOfJobsToKeep) {
this.jobRepository = jobRepository;
this.numberOfJobsToKeep = numberOfJobsToKeep;
LOG.info("KeepLastJobs strategy configured with numberOfJobsToKeep='{}'", numberOfJobsToKeep);
}
/**
* Execute the cleanup of the given repository.
*/
@Scheduled(fixedRate = KEEP_LAST_JOBS_CLEANUP_INTERVAL)
public void doCleanUp() {
final List jobs = jobRepository.findAllJobInfoWithoutMessages();
findJobsToDelete(jobs)
.forEach(jobInfo -> jobRepository.removeIfStopped(jobInfo.getJobId()));
}
private List findJobsToDelete(final List jobs) {
List jobsToDelete = new ArrayList<>();
jobs.stream()
.sorted(comparing(JobInfo::getStarted, reverseOrder()))
.collect(groupingBy(JobInfo::getJobType))
.forEach((jobType, jobExecutions) -> {
Optional lastOkExecution = jobExecutions.stream()
.filter(j -> j.isStopped() && j.getStatus() == OK)
.findFirst();
jobExecutions.stream()
.filter(JobInfo::isStopped)
.skip(numberOfJobsToKeep)
.filter(j -> !(lastOkExecution.isPresent() && lastOkExecution.get().equals(j)))
.forEach(jobsToDelete::add);
});
return jobsToDelete;
}
}