package net.i2p.router.web; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.TreeMap; import net.i2p.data.DataHelper; import net.i2p.router.Job; import net.i2p.router.JobStats; public class JobQueueHelper extends HelperBase { public String getJobQueueSummary() { try { if (_out != null) { renderStatusHTML(_out); return ""; } else { ByteArrayOutputStream baos = new ByteArrayOutputStream(32*1024); renderStatusHTML(new OutputStreamWriter(baos)); return new String(baos.toByteArray()); } } catch (IOException ioe) { ioe.printStackTrace(); return ""; } } /** * Moved from JobQueue * @since 0.8.9 */ private void renderStatusHTML(Writer out) throws IOException { List readyJobs = new ArrayList(8); List timedJobs = new ArrayList(128); List activeJobs = new ArrayList(8); List justFinishedJobs = new ArrayList(8); int numRunners = _context.jobQueue().getJobs(readyJobs, timedJobs, activeJobs, justFinishedJobs); StringBuilder buf = new StringBuilder(32*1024); buf.append("

I2P Job Queue

Job runners: ").append(numRunners); buf.append("
\n"); long now = _context.clock().now(); buf.append("
Active jobs: ").append(activeJobs.size()).append("
    \n"); for (int i = 0; i < activeJobs.size(); i++) { Job j = activeJobs.get(i); buf.append("
  1. [started ").append(DataHelper.formatDuration2(now-j.getTiming().getStartAfter())).append(" ago]: "); buf.append(j.toString()).append("
  2. \n"); } buf.append("
\n"); buf.append("
Just finished jobs: ").append(justFinishedJobs.size()).append("
    \n"); for (int i = 0; i < justFinishedJobs.size(); i++) { Job j = justFinishedJobs.get(i); buf.append("
  1. [finished ").append(DataHelper.formatDuration2(now-j.getTiming().getActualEnd())).append(" ago]: "); buf.append(j.toString()).append("
  2. \n"); } buf.append("
\n"); buf.append("
Ready/waiting jobs: ").append(readyJobs.size()).append("
    \n"); for (int i = 0; i < readyJobs.size(); i++) { Job j = readyJobs.get(i); buf.append("
  1. [waiting "); buf.append(DataHelper.formatDuration2(now-j.getTiming().getStartAfter())); buf.append("]: "); buf.append(j.toString()).append("
  2. \n"); } buf.append("
\n"); out.flush(); buf.append("
Scheduled jobs: ").append(timedJobs.size()).append("
    \n"); TreeMap ordered = new TreeMap(); for (int i = 0; i < timedJobs.size(); i++) { Job j = timedJobs.get(i); ordered.put(Long.valueOf(j.getTiming().getStartAfter()), j); } for (Job j : ordered.values()) { long time = j.getTiming().getStartAfter() - now; buf.append("
  1. ").append(j.getName()).append(" in "); buf.append(DataHelper.formatDuration2(time)).append("
  2. \n"); } buf.append("
\n"); out.flush(); getJobStats(buf); out.flush(); out.write(buf.toString()); } /** * Render the HTML for the job stats. * Moved from JobQueue * @since 0.8.9 */ private void getJobStats(StringBuilder buf) { buf.append("\n" + "" + "" + "\n"); long totRuns = 0; long totExecTime = 0; long avgExecTime = 0; long maxExecTime = -1; long minExecTime = -1; long totPendingTime = 0; long avgPendingTime = 0; long maxPendingTime = -1; long minPendingTime = -1; List tstats = new ArrayList(_context.jobQueue().getJobStats()); Collections.sort(tstats, new JobStatsComparator()); for (JobStats stats : tstats) { buf.append(""); buf.append(""); buf.append(""); buf.append(""); buf.append(""); buf.append(""); buf.append(""); buf.append(""); buf.append(""); buf.append(""); buf.append(""); buf.append("\n"); totRuns += stats.getRuns(); totExecTime += stats.getTotalTime(); if (stats.getMaxTime() > maxExecTime) maxExecTime = stats.getMaxTime(); if ( (minExecTime < 0) || (minExecTime > stats.getMinTime()) ) minExecTime = stats.getMinTime(); totPendingTime += stats.getTotalPendingTime(); if (stats.getMaxPendingTime() > maxPendingTime) maxPendingTime = stats.getMaxPendingTime(); if ( (minPendingTime < 0) || (minPendingTime > stats.getMinPendingTime()) ) minPendingTime = stats.getMinPendingTime(); } if (totRuns != 0) { if (totExecTime != 0) avgExecTime = totExecTime / totRuns; if (totPendingTime != 0) avgPendingTime = totPendingTime / totRuns; } buf.append(""); buf.append(""); buf.append(""); buf.append(""); buf.append(""); buf.append(""); buf.append(""); buf.append(""); buf.append(""); buf.append(""); buf.append(""); buf.append("
JobRunsTimeAvgMaxMinPendingAvgMaxMin
").append(stats.getName()).append("").append(stats.getRuns()).append("").append(DataHelper.formatDuration2(stats.getTotalTime())).append("").append(DataHelper.formatDuration2(stats.getAvgTime())).append("").append(DataHelper.formatDuration2(stats.getMaxTime())).append("").append(DataHelper.formatDuration2(stats.getMinTime())).append("").append(DataHelper.formatDuration2(stats.getTotalPendingTime())).append("").append(DataHelper.formatDuration2(stats.getAvgPendingTime())).append("").append(DataHelper.formatDuration2(stats.getMaxPendingTime())).append("").append(DataHelper.formatDuration2(stats.getMinPendingTime())).append("
").append("SUMMARY").append("").append(totRuns).append("").append(DataHelper.formatDuration2(totExecTime)).append("").append(DataHelper.formatDuration2(avgExecTime)).append("").append(DataHelper.formatDuration2(maxExecTime)).append("").append(DataHelper.formatDuration2(minExecTime)).append("").append(DataHelper.formatDuration2(totPendingTime)).append("").append(DataHelper.formatDuration2(avgPendingTime)).append("").append(DataHelper.formatDuration2(maxPendingTime)).append("").append(DataHelper.formatDuration2(minPendingTime)).append("
\n"); } /** @since 0.8.9 */ private static class JobStatsComparator implements Comparator { public int compare(JobStats l, JobStats r) { return l.getName().compareTo(r.getName()); } } }