/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.importer.job;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
public class JobQueue {
/** job id counter */
AtomicLong counter = new AtomicLong();
/** recent jobs */
ConcurrentHashMap<Long,Task<?>> jobs = new ConcurrentHashMap<Long, Task<?>>();
/** job runner */
//ExecutorService pool = Executors.newCachedThreadPool();
ExecutorService pool = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>()) {
protected <T extends Object> RunnableFuture<T> newTaskFor(Callable<T> callable) {
if (callable instanceof Job) {
return new Task((Job) callable);
}
return super.newTaskFor(callable);
};
protected void beforeExecute(Thread t, Runnable r) {
if (t != null && r instanceof Task) {
((Task)r).started();
}
};
protected void afterExecute(Runnable r, Throwable t) {
if (t != null && r instanceof Task) {
((Task)r).setError(t);
}
};
};
/** job cleaner */
ScheduledExecutorService cleaner = Executors.newSingleThreadScheduledExecutor();
{
cleaner.scheduleAtFixedRate(new Runnable() {
public void run() {
List<Long> toremove = new ArrayList<Long>();
for (Map.Entry<Long, Task<?>> e : jobs.entrySet()) {
if (e.getValue().isCancelled() || (e.getValue().isDone() && e.getValue().isRecieved())) {
toremove.add(e.getKey());
}
}
for (Long l : toremove) {
jobs.remove(l);
}
}
}, 60, 60, TimeUnit.SECONDS);
}
public Long submit(Job<?> task) {
Long jobid = counter.getAndIncrement();
Task t = (Task) pool.submit(task);
t.setId(jobid);
jobs.put(jobid, t);
return jobid;
}
public Task<?> getTask(Long jobid) {
Task<?> t = jobs.get(jobid);
t.recieve();
return t;
}
public List<Task<?>> getTasks() {
return new ArrayList<Task<?>>(jobs.values());
}
public void shutdown() {
cleaner.shutdownNow();
pool.shutdownNow();
}
}