package lsr.paxos.recovery; import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; import lsr.common.Dispatcher; import lsr.common.PriorityTask; public class MockDispatcher implements Dispatcher { private Queue<InnerPriorityTask> activeTasks = new LinkedBlockingQueue<InnerPriorityTask>(); private Queue<InnerPriorityTask> delayedTasks = new LinkedBlockingQueue<InnerPriorityTask>(); private long currentTime = 0; private boolean inDispatcher = false; private boolean forceInDispatcher = false; public PriorityTask dispatch(Runnable task) { InnerPriorityTask priorityTask = new InnerPriorityTask(task, Priority.Normal); activeTasks.add(priorityTask); return priorityTask; } public PriorityTask dispatch(Runnable task, Priority priority) { InnerPriorityTask priorityTask = new InnerPriorityTask(task, priority); activeTasks.add(priorityTask); return priorityTask; } public PriorityTask schedule(Runnable task, Priority priority, long delay) { return scheduleAtFixedRate(task, priority, delay, 1000000000); } public PriorityTask scheduleAtFixedRate(Runnable task, Priority priority, long initialDelay, long period) { InnerPriorityTask priorityTask = new InnerPriorityTask(task, priority, initialDelay + currentTime, period); delayedTasks.add(priorityTask); if (initialDelay == 0) { activeTasks.add(priorityTask); } return priorityTask; } public PriorityTask scheduleWithFixedDelay(Runnable task, Priority priority, long initialDelay, long delay) { return scheduleAtFixedRate(task, priority, initialDelay, delay); } public boolean amIInDispatcher() { return inDispatcher || forceInDispatcher; } public void start() { } public int getQueueSize() { throw new RuntimeException("Not implemented."); } public boolean isBusy() { throw new RuntimeException("Not implemented."); } public int getBusyThreshold() { throw new RuntimeException("Not implemented."); } public void setBusyThreshold(int busyThreshold) { throw new RuntimeException("Not implemented."); } public void forceBeingInDispatcher() { forceInDispatcher = true; } public void execute() { for (InnerPriorityTask task : delayedTasks) { if (task.getNextExecution() <= currentTime) { activeTasks.add(task); } } inDispatcher = true; while (!activeTasks.isEmpty()) { InnerPriorityTask task = activeTasks.poll(); if (task.isCanceled()) { continue; } task.run(); } inDispatcher = false; } /** * Moves the current time specified number of milliseconds to the future. * * @param milliseconds */ public void advanceTime(long milliseconds) { currentTime += milliseconds; } private static class InnerPriorityTask implements PriorityTask { private final Runnable task; private final Priority priority; private boolean canceled = false; private long nextExecution = 0; private long period = 0; public InnerPriorityTask(Runnable task, Priority priority) { this.task = task; this.priority = priority; } public InnerPriorityTask(Runnable task, Priority priority, long initialDelay, long period) { this.task = task; this.priority = priority; this.nextExecution = initialDelay; this.period = period; } public void cancel() { canceled = true; } public void run() { task.run(); nextExecution += period; } public Priority getPriority() { return priority; } public long getDelay() { return 0; } public boolean isCanceled() { return canceled; } public long getSeqNum() { return 0; } public long getNextExecution() { return nextExecution; } } }