code: @Override
     public double getSortProcessingRate(long currentTime) {
       long timeSpentSorting = 0;
       float progress = 0;
       Phase phase = getPhase();
       long sortFinishTime = getSortFinishTime();
       long shuffleFinishTime = getShuffleFinishTime();
       
       if (phase == Phase.SHUFFLE ) {
         return 0;
       } else if (getPhase() == Phase.SORT) {
         if (shuffleFinishTime < currentTime) {
           LOG.error("Shuffle finish time is " + shuffleFinishTime + 
               " which is < current time " + currentTime + 
               " in " + this.getTaskID());
         }
         timeSpentSorting =  currentTime - shuffleFinishTime;
         progress = getProgress() - (float)1.0/3;
         if (progress < 0) {
           LOG.error("Shuffle progress calculated to be " + progress + 
               " in task status for  " + this.getTaskID() + ".  Settings to 0");
           progress = 0;
         }
       } else if (getPhase() == Phase.REDUCE) {
         // when it is reduce phase, use 33%/(sort finish time - shuffle 
         // finish time as the progress rate. Using percentages instead of bytes
         // as it is tricky
         progress = (float)1.0/3;
         if (shuffleFinishTime <= sortFinishTime) {
           LOG.error("Shuffle finish fime is " + shuffleFinishTime + 
               " which is <= sort finish time " + sortFinishTime + 
               " in " + this.getTaskID());
           return 0;
         }
         timeSpentSorting = sortFinishTime - shuffleFinishTime;
       }
       
       sortProcessingRate = progress/timeSpentSorting; 
       return sortProcessingRate;
     }
docs: for sort phase, use the accumulated progress rate as the processing rate