package com.datascience.scheduler;
import com.datascience.core.base.LObject;
import com.datascience.core.base.Project;
import com.datascience.core.base.Worker;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalNotification;
import org.apache.log4j.Logger;
import java.util.concurrent.TimeUnit;
public class CachedScheduler<T> extends Scheduler<T> {
private static Logger logger = Logger.getLogger(CachedScheduler.class);
private Cache<String, LObject<T>> polled;
private long pauseDuration;
private TimeUnit pauseUnit;
public CachedScheduler() { }
public CachedScheduler(Project<T, ?, ?, ?> project, IPriorityCalculator<T> calculator, long pauseDuration, TimeUnit pauseUnit) {
super(project, calculator);
setUpCache(pauseDuration, pauseUnit);
}
@Override
public void update() {
polled.invalidateAll();
super.update();
}
@Override
public void update(LObject<T> object) {
if (polled.getIfPresent(object.getName()) != null) {
polled.invalidate(object.getName());
} else {
super.update(object);
}
}
@Override
public LObject<T> nextObject() {
polled.cleanUp();
LObject<T> object = queue.getAndRemoveFirst();
if (object != null) {
polled.put(object.getName(), object);
}
return object;
}
@Override
public LObject<T> nextObject(Worker worker) {
polled.cleanUp();
LObject<T> object = super.nextObject(worker);
if (object != null) {
polled.put(object.getName(), object);
queue.remove(object);
}
return object;
}
public void setUpCache(long pauseDuration, TimeUnit pauseUnit) {
polled = CacheBuilder.newBuilder()
.expireAfterWrite(pauseDuration, pauseUnit)
.removalListener(getRemovalListener())
.build();
this.pauseDuration = pauseDuration;
this.pauseUnit = pauseUnit;
}
public long getPauseDuration() {
return pauseDuration;
}
public TimeUnit getPauseUnit() {
return pauseUnit;
}
private RemovalListener<String, LObject<T>> getRemovalListener() {
return new RemovalListener<String, LObject<T>>() {
@Override
public void onRemoval(RemovalNotification<String, LObject<T>> notification) {
try {
CachedScheduler.super.update(notification.getValue());
} catch (Exception e) {
logger.error("CachedScheduler on eviction", e);
}
}
};
}
@Override
public String getId(){
return "cachedscheduler";
}
}