package org.atomnuke.task.threading; import java.util.Iterator; import java.util.Map; import java.util.TreeMap; import java.util.concurrent.Future; import org.atomnuke.service.ServiceContext; /** * * @author zinic */ public class ExecutionManagerImpl implements ExecutionManager { private final Map<Long, TrackedFuture> taskFutures; private final ExecutionQueue executionQueue; private final StateManager stateManager; public ExecutionManagerImpl(ExecutionQueue executionQueue) { this.executionQueue = executionQueue; stateManager = new StateManager(State.NEW); taskFutures = new TreeMap<Long, TrackedFuture>(); } private synchronized Map<Long, TrackedFuture> taskFutures() { for (Iterator<TrackedFuture> itr = taskFutures.values().iterator(); itr.hasNext();) { final TrackedFuture nextTask = itr.next(); if (nextTask.done()) { itr.remove(); } } return taskFutures; } @Override public void init(ServiceContext sc) { stateManager.update(State.STARTING); stateManager.update(State.READY); } @Override public void destroy() { stateManager.update(State.STOPPING); // Shut down the execution queue we're using executionQueue.destroy(); stateManager.update(State.DESTROYED); } @Override public synchronized Future submit(Runnable r) { return executionQueue.submit(r); } @Override public synchronized TrackedFuture submitTracked(long taskId, Runnable r) { final TrackedFuture taskFuture = new TrackedFuture(executionQueue.submit(r), taskId); taskFutures.put(taskId, taskFuture); return taskFuture; } @Override public State state() { final State state = stateManager.state(); switch (state) { case STOPPING: case DESTROYED: break; case DRAINING: if (!executionQueue.isFull()) { stateManager.update(State.READY); } break; default: if (executionQueue.isFull()) { stateManager.update(State.DRAINING); } } return stateManager.state(); } @Override public boolean submitted(long taskId) { return taskFutures().containsKey(taskId); } }