package oncue.backingstore;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import oncue.common.messages.Job;
import oncue.common.settings.Settings;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import akka.actor.ActorSystem;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
/**
* A simple in-memory backing store, which is not persistent across restarts. Use this for testing
* only!
*/
public class InMemoryBackingStore extends AbstractBackingStore {
private List<Job> scheduledJobs = new ArrayList<>();
private List<Job> unscheduledJobs = new ArrayList<>();
private List<Job> completedJobs = new ArrayList<>();
private List<Job> failedJobs = new ArrayList<>();
private long nextJobID = 1;
public InMemoryBackingStore(ActorSystem system, Settings settings) {
super(system, settings);
}
@Override
public void addScheduledJobs(List<Job> scheduledJobs) {
this.scheduledJobs.addAll(scheduledJobs);
}
@Override
public void addUnscheduledJob(Job job) {
this.unscheduledJobs.add(job);
}
@Override
public List<Job> getCompletedJobs() {
return completedJobs;
}
@Override
public List<Job> getFailedJobs() {
return failedJobs;
}
@Override
public long getNextJobID() {
return this.nextJobID++;
}
@Override
public void persistJobFailure(Job job) {
failedJobs.add(job);
}
@Override
public void persistJobProgress(Job job) {
for (Job scheduledJob : scheduledJobs) {
if (scheduledJob.getId() == job.getId()) {
scheduledJob.setProgress(job.getProgress());
if (job.getState() == Job.State.COMPLETE) {
completedJobs.add(job);
}
break;
}
}
}
@Override
public void removeScheduledJobById(long jobId) {
removeJobById(scheduledJobs, jobId);
}
@Override
public void removeUnscheduledJobById(long jobId) {
removeJobById(unscheduledJobs, jobId);
}
@Override
public List<Job> restoreJobs() {
return Collections.emptyList();
}
@Override
public void removeCompletedJobById(long jobId) {
removeJobById(completedJobs, jobId);
}
@Override
public void removeFailedJobById(long jobId) {
removeJobById(failedJobs, jobId);
}
@Override
public int cleanupJobs(boolean includeFailedJobs, Duration expirationAge) {
List<Job> expiredCompletedJobs = new ArrayList<>();
for (Job completedJob : completedJobs) {
DateTime expirationThreshold = DateTime.now().minus(expirationAge.getMillis());
boolean isExpired = completedJob.getCompletedAt().isBefore(
expirationThreshold.toInstant());
if (isExpired) {
expiredCompletedJobs.add(completedJob);
}
}
completedJobs.removeAll(expiredCompletedJobs);
if (!includeFailedJobs) {
return expiredCompletedJobs.size();
}
List<Job> expiredFailedJobs = new ArrayList<>();
for (Job failedJob : failedJobs) {
DateTime expirationThreshold = DateTime.now().minus(expirationAge.getMillis());
boolean isExpired = failedJob.getCompletedAt()
.isBefore(expirationThreshold.toInstant());
if (isExpired) {
expiredFailedJobs.add(failedJob);
}
}
expiredFailedJobs.removeAll(expiredFailedJobs);
return expiredFailedJobs.size() + expiredCompletedJobs.size();
}
/**
* Remove jobs from collections by ID rather than object equality.
* @param jobList
* @param job
*/
private void removeJobById(List<Job> jobList, final long jobId) {
Iterables.removeIf(jobList, new Predicate<Job>() {
@Override
public boolean apply(Job input) {
return jobId == input.getId();
}
});
}
}