package org.threadly.concurrent;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
import org.threadly.concurrent.AbstractPriorityScheduler.QueueSet;
import org.threadly.concurrent.AbstractPriorityScheduler.RecurringDelayTaskWrapper;
import org.threadly.concurrent.AbstractPriorityScheduler.RecurringRateTaskWrapper;
import org.threadly.concurrent.AbstractPriorityScheduler.TaskWrapper;
import org.threadly.concurrent.NoThreadScheduler.NoThreadRecurringDelayTaskWrapper;
import org.threadly.concurrent.NoThreadScheduler.NoThreadRecurringRateTaskWrapper;
import org.threadly.util.Clock;
/**
* PLEASE IGNORE THIS CLASS, DO NOT USE
* <p>
* This internal class is only used for threadly out of package wrappers to be able to directly
* access protected functionality. This is primarily done to avoid excessive checking, or short
* cut logic in order to get performance gains.
* <p>
* Because of that, this is highly specialized and not likely to be useful to anyone else.
*
* @since 4.6.0
*/
public class ThreadlyInternalAccessor {
/**
* Used for gaining compatibility with java.util.concurrent when a {@link Delayed} object is
* needed.
*
* @param pScheduler Scheduler to submit task to
* @param task Task to be submitted
* @param priority Priority for task to be submitted at
* @param delayInMillis Delay for task execution
* @return Delayed implementation which corresponds to executed task
*/
public static Delayed doScheduleAndGetDelayed(AbstractPriorityScheduler pScheduler, Runnable task,
TaskPriority priority, long delayInMillis) {
return new DelayedTaskWrapper(pScheduler.doSchedule(task, delayInMillis, priority));
}
/**
* Used for gaining compatibility with java.util.concurrent when a {@link Delayed} object is
* needed.
*
* @param pScheduler Scheduler to submit task to
* @param task Task to be submitted
* @param priority Priority for task to be submitted at
* @param initialDelay initial delay for task to execute
* @param periodInMillis recurring delay for task to execute
* @return Delayed implementation which corresponds to executed task
*/
public static Delayed doScheduleAtFixedRateAndGetDelayed(PriorityScheduler pScheduler,
Runnable task, TaskPriority priority,
long initialDelay, long periodInMillis) {
QueueSet queueSet = pScheduler.taskQueueManager.getQueueSet(priority);
RecurringRateTaskWrapper rrtw =
new RecurringRateTaskWrapper(task, queueSet,
Clock.accurateForwardProgressingMillis() + initialDelay,
periodInMillis);
pScheduler.addToScheduleQueue(queueSet, rrtw);
return new DelayedTaskWrapper(rrtw);
}
/**
* Used for gaining compatibility with java.util.concurrent when a {@link Delayed} object is
* needed.
*
* @param pScheduler Scheduler to submit task to
* @param task Task to be submitted
* @param priority Priority for task to be submitted at
* @param initialDelay initial delay for task to execute
* @param delayInMs recurring delay for task to execute
* @return Delayed implementation which corresponds to executed task
*/
public static Delayed doScheduleWithFixedDelayAndGetDelayed(PriorityScheduler pScheduler,
Runnable task, TaskPriority priority,
long initialDelay, long delayInMs) {
QueueSet queueSet = pScheduler.taskQueueManager.getQueueSet(priority);
RecurringDelayTaskWrapper rdtw =
new RecurringDelayTaskWrapper(task, queueSet,
Clock.accurateForwardProgressingMillis() + initialDelay,
delayInMs);
pScheduler.addToScheduleQueue(queueSet, rdtw);
return new DelayedTaskWrapper(rdtw);
}
/**
* Used for gaining compatibility with java.util.concurrent when a {@link Delayed} object is
* needed.
*
* @param scheduler Scheduler to submit task to
* @param task Task to be submitted
* @param priority Priority for task to be submitted at
* @param initialDelay initial delay for task to execute
* @param periodInMillis recurring delay for task to execute
* @return Delayed implementation which corresponds to executed task
*/
public static Delayed doScheduleAtFixedRateAndGetDelayed(SingleThreadScheduler scheduler,
Runnable task, TaskPriority priority,
long initialDelay, long periodInMillis) {
NoThreadScheduler nts = scheduler.getRunningScheduler();
QueueSet queueSet = nts.queueManager.getQueueSet(priority);
NoThreadRecurringRateTaskWrapper rt =
nts.new NoThreadRecurringRateTaskWrapper(task, queueSet,
Clock.accurateForwardProgressingMillis() +
initialDelay,
periodInMillis);
queueSet.addScheduled(rt);
return new DelayedTaskWrapper(rt);
}
/**
* Used for gaining compatibility with java.util.concurrent when a {@link Delayed} object is
* needed.
*
* @param scheduler Scheduler to submit task to
* @param task Task to be submitted
* @param priority Priority for task to be submitted at
* @param initialDelay initial delay for task to execute
* @param delayInMs recurring delay for task to execute
* @return Delayed implementation which corresponds to executed task
*/
public static Delayed doScheduleWithFixedDelayAndGetDelayed(SingleThreadScheduler scheduler,
Runnable task, TaskPriority priority,
long initialDelay, long delayInMs) {
NoThreadScheduler nts = scheduler.getRunningScheduler();
QueueSet queueSet = nts.queueManager.getQueueSet(priority);
NoThreadRecurringDelayTaskWrapper rdt =
nts.new NoThreadRecurringDelayTaskWrapper(task, queueSet,
Clock.accurateForwardProgressingMillis() +
initialDelay,
delayInMs);
queueSet.addScheduled(rdt);
return new DelayedTaskWrapper(rdt);
}
/**
* Small wrapper to convert from a {@link PriorityScheduler.TaskWrapper} into a Delayed
* interface.
*
* @since 4.6.0
*/
protected static class DelayedTaskWrapper implements Delayed {
private final TaskWrapper task;
public DelayedTaskWrapper(TaskWrapper task) {
this.task = task;
}
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(task.getRunTime() - Clock.accurateForwardProgressingMillis(),
TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
if (this == o) {
return 0;
} else if (o instanceof DelayedTaskWrapper) {
return (int)(task.getRunTime() - ((DelayedTaskWrapper)o).task.getRunTime());
} else {
long thisDelay = this.getDelay(TimeUnit.MILLISECONDS);
long otherDelay = o.getDelay(TimeUnit.MILLISECONDS);
if (thisDelay == otherDelay) {
return 0;
} else if (thisDelay > otherDelay) {
return 1;
} else {
return -1;
}
}
}
}
}