package org.atomnuke.task.manager.impl; import java.util.concurrent.TimeUnit; import org.atomnuke.task.ManagedTask; import org.atomnuke.task.TaskHandle; import org.atomnuke.task.manager.TaskManager; import org.atomnuke.task.manager.TaskTracker; import org.atomnuke.task.polling.PollingController; import org.atomnuke.task.polling.TaskFutureImpl; import org.atomnuke.task.threading.ExecutionLifeCycle; import org.atomnuke.task.threading.ExecutionManager; import org.atomnuke.util.TimeValue; /** * * @author zinic */ public class GenericTaskManger implements TaskManager { private static final TimeValue DEFAULT_SLEEP_INTERVAL = new TimeValue(3, TimeUnit.MILLISECONDS); private final ExecutionManager executionManager; private final TaskTracker taskTracker; public GenericTaskManger(ExecutionManager executionManager, TaskTracker taskTracker) { this.executionManager = executionManager; this.taskTracker = taskTracker; } @Override public State state() { if (!taskTracker.active()) { return State.DESTROYED; } switch (executionManager.state()) { case NEW: case STARTING: return State.NEW; case STOPPING: case DESTROYED: return State.DESTROYED; } return State.READY; } @Override public void destroy() { // Cancel all of the executing tasks for (ManagedTask managedTask : taskTracker.activeTasks()) { managedTask.handle().cancellationRemote().cancel(); } } @Override public TimeValue scheduleTasks() { final TimeValue now = TimeValue.now(); for (ManagedTask managedTask : taskTracker.activeTasks()) { final PollingController pollingController = managedTask.pollingController(); final TaskHandle taskHandle = managedTask.handle(); // Sould this task be scheduled? If so, is the task already in the execution queue? Reentrancy will also make a task eligible for polling. if (pollingController.shouldPoll(now) && (taskHandle.reenterant() || !executionManager.submitted(taskHandle.id()))) { // Create a new future for this scheduling pass of the task - this is used to communicate progress final TaskFutureImpl taskFuture = new TaskFutureImpl(); // Tell the polling controller that we're being tasked before actually submitting the task pollingController.taskScheduled(taskFuture); // Submit the runnable representation of the task executionManager.submitTracked(taskHandle.id(), new ExecutionLifeCycle(managedTask, taskFuture)); } } // We check against a new time value representing now since scheduling may have taken time beyond the grainularity of the timer return taskTracker.hasTasksToSchedule(TimeValue.now()) ? TimeValue.zero() : DEFAULT_SLEEP_INTERVAL; } }