package org.atomnuke.task.manager.impl; import org.atomnuke.task.manager.Tasker; import org.atomnuke.plugin.InstanceContext; import org.atomnuke.plugin.operation.ComplexOperation; import org.atomnuke.plugin.operation.OperationFailureException; import org.atomnuke.service.gc.ReclamationHandler; import org.atomnuke.task.TaskHandle; import org.atomnuke.task.atom.impl.EnvironmentAwareManagedTask; import org.atomnuke.task.atom.impl.TaskHandleImpl; import org.atomnuke.task.manager.TaskTracker; import org.atomnuke.task.polling.PollingController; import org.atomnuke.task.polling.TimeIntervalPollingController; import org.atomnuke.task.threading.ExecutionManager; import org.atomnuke.task.threading.InstanceContextRunnableWrapper; import org.atomnuke.util.TimeValue; import org.atomnuke.util.lifecycle.runnable.ReclaimableTask; import org.atomnuke.util.remote.AtomicCancellationRemote; import org.atomnuke.util.remote.CancellationRemote; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author zinic */ public class FalloutTasker implements Tasker { private final Logger LOG = LoggerFactory.getLogger(FalloutTasker.class); private final ComplexOperation<ReclaimableTask, TaskHandle> ENLISTED_OPERATION = new ComplexOperation<ReclaimableTask, TaskHandle>() { @Override public void perform(ReclaimableTask instance, TaskHandle argument) throws OperationFailureException { instance.enlisted(argument); } }; private final ReclamationHandler reclamationHandler; private final ExecutionManager executionManager; private final TaskTracker taskTracker; public FalloutTasker(ReclamationHandler reclamationHandler, ExecutionManager executionManager, TaskTracker taskTracker) { this.reclamationHandler = reclamationHandler; this.executionManager = executionManager; this.taskTracker = taskTracker; } @Override public TaskHandle queueTask(InstanceContext<? extends ReclaimableTask> instanceContext, PollingController pollingController) { final CancellationRemote cancellationRemote = new AtomicCancellationRemote(); final TaskHandle newHandle = new TaskHandleImpl(false, cancellationRemote); try { addTask(instanceContext, newHandle, pollingController); } catch (OperationFailureException ofe) { cancellationRemote.cancel(); } return newHandle; } @Override public void queueAction(InstanceContext<? extends ReclaimableTask> runnableContext) { executionManager.submit(new InstanceContextRunnableWrapper(runnableContext)); } @Override public TaskHandle pollTask(InstanceContext<? extends ReclaimableTask> instanceContext, TimeValue pollingInterval) { final CancellationRemote cancellationRemote = reclamationHandler.watch(instanceContext); final TaskHandle newHandle = new TaskHandleImpl(false, cancellationRemote); try { ((InstanceContext<ReclaimableTask>) instanceContext).<TaskHandle>perform(ENLISTED_OPERATION, newHandle); taskTracker.enlistAction(new EnvironmentAwareManagedTask(instanceContext, newHandle, new TimeIntervalPollingController(newHandle, pollingInterval))); } catch (OperationFailureException ofe) { LOG.error(ofe.getMessage(), ofe); cancellationRemote.cancel(); } return newHandle; } private void addTask(InstanceContext<? extends ReclaimableTask> runnableContext, TaskHandle newHandle, PollingController pollingController) throws OperationFailureException { ((InstanceContext<ReclaimableTask>) runnableContext).<TaskHandle>perform(ENLISTED_OPERATION, newHandle); taskTracker.enlistAction(new EnvironmentAwareManagedTask(runnableContext, newHandle, pollingController)); } }