/** * Constructs a new {@link NoThreadSchedulerStatisticTracker} scheduler, specifying all available * construction options. * * @param defaultPriority Default priority for tasks which are submitted without any specified priority * @param maxWaitForLowPriorityInMs time low priority tasks to wait if there are high priority tasks ready to run * @param maxStatisticWindowSize maximum number of samples to keep internally * @param accurateTime {@code true} to ensure that delays and durations are not under reported */ public NoThreadSchedulerStatisticTracker(TaskPriority defaultPriority, long maxWaitForLowPriorityInMs, int maxStatisticWindowSize, boolean accurateTime) { super(defaultPriority, maxWaitForLowPriorityInMs); this.statsManager = new PriorityStatisticManager(maxStatisticWindowSize, accurateTime); }
@Override public double getAverageExecutionDelay(TaskPriority priority) { return statsManager.getAverageExecutionDelay(priority); }
@Override public double getAverageExecutionDuration() { return statsManager.getAverageExecutionDuration(); }
public List<Long> getExecutionDelaySamples(TaskPriority priority) { if (priority == null) { return getExecutionDelaySamples(); } return new ArrayList<>(getExecutionDelaySamplesInternal(priority)); }
public List<Long> getExecutionDurationSamples(TaskPriority priority) { if (priority == null) { return getExecutionDurationSamples(); } return new ArrayList<>(getExecutionDurationSamplesInternal(priority)); }
@Override public List<Long> getExecutionDurationSamples() { return statsManager.getExecutionDurationSamples(); }
@Override public TaskWrapper workerIdle(Worker worker) { TaskWrapper result = super.workerIdle(worker); // may not be a wrapper for internal tasks like shutdown if (result != null && result.getContainedRunnable() instanceof TaskStatWrapper) { long taskDelay = Clock.lastKnownForwardProgressingMillis() - result.getPureRunTime(); TaskStatWrapper statWrapper = (TaskStatWrapper)result.getContainedRunnable(); ConcurrentArrayList<Long> priorityStats = statsManager.getExecutionDelaySamplesInternal(statWrapper.priority); synchronized (priorityStats.getModificationLock()) { priorityStats.add(taskDelay); statsManager.trimWindow(priorityStats); } } return result; } }
@Override public List<Long> getExecutionDelaySamples(TaskPriority priority) { return statsManager.getExecutionDelaySamples(priority); }
@Override public Map<Double, Long> getExecutionDelayPercentiles(TaskPriority priority, double... percentiles) { return statsManager.getExecutionDelayPercentiles(priority, percentiles); }
@Override public Map<Double, Long> getExecutionDurationPercentiles(TaskPriority priority, double... percentiles) { return statsManager.getExecutionDurationPercentiles(priority, percentiles); }
public void resetCollectedStats() { for (TaskPriority p : TaskPriority.values()) { getExecutionDelaySamplesInternal(p).clear(); getExecutionDurationSamplesInternal(p).clear(); } }
public double getAverageExecutionDelay(TaskPriority priority) { if (priority == null) { return getAverageExecutionDelay(); } List<Long> stats = getExecutionDelaySamples(priority); if (stats.isEmpty()) { return -1; } return StatisticsUtils.getAverage(stats); }
public long getTotalExecutionCount(TaskPriority priority) { if (priority == null) { return getTotalExecutionCount(); } return getExecutionCount(priority).sum(); }
/** * Used to track how long tasks are tacking to complete. * * @param taskPair wrapper for task that completed */ protected void trackTaskFinish(Pair<Thread, TaskStatWrapper> taskPair) { long finishTime = accurateTime ? Clock.accurateForwardProgressingMillis() : Clock.lastKnownForwardProgressingMillis(); ConcurrentArrayList<Long> runDurations = getExecutionDurationSamplesInternal(taskPair.getRight().priority); Long startTime = runningTasks.remove(taskPair); synchronized (runDurations.getModificationLock()) { runDurations.add(finishTime - startTime); trimWindow(runDurations); } }
/** * Called at the start of execution to track statistics around task execution. * * @param taskPair Wrapper that is about to be executed */ protected void trackTaskStart(Pair<Thread, TaskStatWrapper> taskPair) { getExecutionCount(taskPair.getRight().priority).increment(); runningTasks.put(taskPair, Clock.accurateForwardProgressingMillis()); }
@Override public List<Long> getExecutionDurationSamples() { return statsManager.getExecutionDurationSamples(); }
@Override protected TaskWrapper getNextReadyTask() { TaskWrapper result = super.getNextReadyTask(); // may not be a wrapper for internal tasks like shutdown if (result != null && result.getContainedRunnable() instanceof TaskStatWrapper) { long taskDelay = Clock.lastKnownForwardProgressingMillis() - result.getPureRunTime(); TaskStatWrapper statWrapper = (TaskStatWrapper)result.getContainedRunnable(); ConcurrentArrayList<Long> priorityStats = statsManager.getExecutionDelaySamplesInternal(statWrapper.priority); synchronized (priorityStats.getModificationLock()) { priorityStats.add(taskDelay); statsManager.trimWindow(priorityStats); } } return result; } }
@Override public List<Long> getExecutionDelaySamples() { return statsManager.getExecutionDelaySamples(); }
public List<Long> getExecutionDelaySamples(TaskPriority priority) { if (priority == null) { return getExecutionDelaySamples(); } return new ArrayList<>(getExecutionDelaySamplesInternal(priority)); }
public List<Long> getExecutionDurationSamples(TaskPriority priority) { if (priority == null) { return getExecutionDurationSamples(); } return new ArrayList<>(getExecutionDurationSamplesInternal(priority)); }