package com.stella.framework.scheduler;
import org.apache.log4j.Logger;
import com.stella.framework.job.Job;
import com.stella.framework.job.JobThread;
public class RunSchedulerQueue {
private static final Logger logger = Logger.getLogger(RunSchedulerQueue.class);
private int maximumConcurrentJobCount;
private int runningJobCount;
private RunScheduler runScheduler;
private Thread[] runningQueue;
private int[] runningJobIds;
private Object lock = new Object();
public RunSchedulerQueue(RunScheduler runScheduler, final int maximumConcurrentJobCount) {
runningJobCount = 0;
this.runScheduler = runScheduler;
this.maximumConcurrentJobCount = maximumConcurrentJobCount;
runningQueue = new Thread[maximumConcurrentJobCount];
runningJobIds = new int[maximumConcurrentJobCount];
for(int i = 0; i < maximumConcurrentJobCount; i++) {
runningQueue[i] = null;
runningJobIds[i] = -1;
}
}
public boolean addJob(Job job) {
synchronized(lock) {
for(int i = 0; i < maximumConcurrentJobCount; i++) {
if(runningQueue[i] == null) {
runningJobIds[i] = job.getUniqueId();
runningQueue[i] = new Thread(new JobThread(runScheduler, job));
runningQueue[i].start();
runningJobCount++;
logger.info("run_count = " + runningJobCount);
return true;
}
}
}
return false;
}
public void waitForCompletion() {
for(int i = 0; i < maximumConcurrentJobCount; i++) {
if(runningQueue[i] != null) {
try {
runningQueue[i].wait();
} catch (InterruptedException e) {
logger.error(e.getMessage());
}
}
}
}
private void freeRunSlot(final int runSlotNumber) {
runningJobIds[runSlotNumber] = -1;
runningQueue[runSlotNumber] = null;
}
public void removeRunningJob(Job job) {
synchronized(lock) {
final int jobId = job.getUniqueId();
for(int i = 0; i < maximumConcurrentJobCount; i++) {
if(runningJobIds[i] == jobId) {
freeRunSlot(i);
runningJobCount--;
lock.notifyAll();
return;
}
}
}
}
public int getRunningJobCount() {
synchronized(lock) {
return runningJobCount;
}
}
public boolean hasCapacity() {
synchronized(lock) {
while(runningJobCount >= maximumConcurrentJobCount) {
try {
logger.debug(String.format("waiting for run_queue to free [%d/%d]", runningJobCount, maximumConcurrentJobCount));
lock.wait();
} catch (InterruptedException e) {
break;
}
}
}
return(runningJobCount < maximumConcurrentJobCount);
}
}