Package org.apache.hadoop.mapred

Source Code of org.apache.hadoop.mapred.SimulatorTaskTracker$SimulatorTaskInProgress

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.mapred;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.mapred.TaskStatus.Phase;
import org.apache.hadoop.mapred.TaskStatus.State;
import org.apache.hadoop.tools.rumen.TaskAttemptInfo;
import org.apache.hadoop.tools.rumen.ReduceTaskAttemptInfo;
// Explicitly use the new api, older o.a.h.mapred.TaskAttemptID is deprecated
import org.apache.hadoop.mapreduce.TaskAttemptID;

/**
* This class simulates a {@link TaskTracker}. Its main purpose is to call heartbeat()
* of the simulated Job Tracker with apropriately updated statuses of the
* tasks assigned to it.
*
* The events emitted and consumed are HeartbeatEvent and
* TaskAttemptCompletionEvent .
*
* Internal naming convention: accept() dispatches simulation events to
* process*Event() methods. heartbeat() dispactches task tracker actions to
* handle*Action() methods.
*/
public class SimulatorTaskTracker implements SimulatorEventListener {
  /** The name of the task tracker. */
  protected final String taskTrackerName;
  /** The name of the host the task tracker is running on. */
  protected final String hostName;
  /** The http port the simulated task tracker reports to the jobtracker. */ 
  protected final int httpPort = 80;
  /** Number of map slots. */
  protected final int maxMapSlots;
  /** Number of reduce slots. */
  protected final int maxReduceSlots;
  /** The job tracker this task tracker is a slave of. */
  protected final InterTrackerProtocol jobTracker;

  /**
   * State of and bookkeeping information for all tasks assigned to the task
   * tracker. Contains all the information about running or completed but
   * not yet reported tasks. We manage it in a mark & sweep garbage collector
   * manner. We insert tasks on launch, mark them on completion, and remove
   * completed tasks at heartbeat() reports.
   */
  protected Map<TaskAttemptID, SimulatorTaskInProgress> tasks =
      new HashMap<TaskAttemptID, SimulatorTaskInProgress>();
  /**
   * Number of map slots allocated to tasks in RUNNING state on this task
   * tracker. Must be in sync with the tasks map above.
   */
  private int usedMapSlots = 0;
  /**
   * Number of reduce slots allocated to tasks in RUNNING state on this task
   * tracker. Must be in sync with the tasks map above.
   */
  private int usedReduceSlots = 0
  /**
   * True if the jobTracker.heartbeat() call to be made is the first one.
   * We need this to mimick the InterTrackerProtocol properly.
   */
  private boolean firstHeartbeat = true;

  // last heartbeat response recieved
  private short heartbeatResponseId = -1;

  /**
   * Task attempt ids for which TaskAttemptCompletionEvent was created but the
   * task attempt got killed.
   */
  private Set<TaskAttemptID> orphanTaskCompletions =
    new HashSet<TaskAttemptID>();

  /** The log object to send our messages to; only used for debugging. */
  private static final Log LOG = LogFactory.getLog(SimulatorTaskTracker.class);
 
  /**
   * Constructs a task tracker.
   *
   * @param jobTracker the SimulatorJobTracker we talk to
   * @param taskTrackerName the task tracker name to report, otherwise unused
   * @param hostName the host name to report, otherwise unused
   * @param maxMapTasks the number of map slots
   * @param maxReduceTasks the number of reduce slots
   */
  public SimulatorTaskTracker(InterTrackerProtocol jobTracker,
                              String taskTrackerName, String hostName,
                              int maxMapTasks, int maxReduceTasks) {
    LOG.debug("SimulatorTaskTracker constructor, taskTrackerName=" +
              taskTrackerName);

    this.jobTracker = jobTracker;   
    this.taskTrackerName = taskTrackerName;
    this.hostName = hostName;
    this.maxMapSlots = maxMapTasks;
    this.maxReduceSlots = maxReduceTasks;
  }
 
  /**
   * Processes a simulation event.
   *
   * @param event the event to process, should be an instance of HeartbeatEvent
   *        or TaskAttemptCompletionEvent
   * @return the list of new events generated in response
   */
  @Override
  public List<SimulatorEvent> accept(SimulatorEvent event) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Accepted event " + event);
    }

    if (event instanceof HeartbeatEvent) {
      return processHeartbeatEvent((HeartbeatEvent)event);
    } else if (event instanceof TaskAttemptCompletionEvent) {
      return processTaskAttemptCompletionEvent((TaskAttemptCompletionEvent)
                                               event);
    } else {
      throw new IllegalArgumentException("Unhandled event "+event);
    }
  }
 
  /**
   * Called once at the start of the simulation.
   *
   * @param when Time when the task tracker starts.
   * @return the initial HeartbeatEvent for ourselves.
   */
  public List<SimulatorEvent> init(long when) {
    LOG.debug("TaskTracker starting up, current simulation time=" + when);

    return Collections.<SimulatorEvent>singletonList(new HeartbeatEvent(this, when))
  }
  /**
   * Stops running a task attempt on the task tracker. It also updates the
   * number of available slots accordingly.
   *
   * @param finalStatus the TaskStatus containing the task id and final
   *        status of the task attempt. This rountine asserts a lot of the
   *        finalStatus params, in case it is coming from a task attempt
   *        completion event sent to ourselves. Only the run state, finish time,
   *        and progress fields of the task attempt are updated.
   * @param now Current simulation time, used for assert only
   */
  private void finishRunningTask(TaskStatus finalStatus, long now) {
    TaskAttemptID taskId = finalStatus.getTaskID();
    if (LOG.isDebugEnabled()) {
      LOG.debug("Finishing running task id=" + taskId + ", now=" + now);
    }

    SimulatorTaskInProgress tip = tasks.get(taskId);
    if (tip == null) {
      throw new IllegalArgumentException("Unknown task attempt " + taskId
          + " completed");
    }
    TaskStatus currentStatus = tip.getTaskStatus();
    if (currentStatus.getRunState() != State.RUNNING) {
      throw new IllegalArgumentException(
          "Task attempt to finish is not running: " + tip);
    }

    // Check that finalStatus describes a task attempt that has just been
    // completed
    State finalRunState = finalStatus.getRunState();
    if (finalRunState != State.SUCCEEDED && finalRunState != State.FAILED
        && finalRunState != State.KILLED) {
      throw new IllegalArgumentException(
          "Final run state for completed task can't be : " + finalRunState
              + " " + tip);
    }

    if (now != finalStatus.getFinishTime()) {
      throw new IllegalArgumentException(
          "Current time does not match task finish time: now=" + now
              + ", finish=" + finalStatus.getFinishTime());
    }

    if (currentStatus.getIsMap() != finalStatus.getIsMap()
        || currentStatus.getNumSlots() != finalStatus.getNumSlots()
        || currentStatus.getPhase() != finalStatus.getPhase()
        || currentStatus.getStartTime() != finalStatus.getStartTime()) {
      throw new IllegalArgumentException(
          "Current status does not match final status");
    }

    // We can't assert getShuffleFinishTime() and getSortFinishTime() for
    // reduces as those were unknown when the task attempt completion event
    // was created. We have not called setMapFinishTime() for maps either.
    // If we were really thorough we could update the progress of the task
    // and check if it is consistent with finalStatus.

    // If we've got this far it is safe to update the task status
    currentStatus.setRunState(finalStatus.getRunState());
    currentStatus.setFinishTime(finalStatus.getFinishTime());
    currentStatus.setProgress(finalStatus.getProgress());

    // and update the free slots
    int numSlots = currentStatus.getNumSlots();
    if (tip.isMapTask()) {
      usedMapSlots -= numSlots;
      if (usedMapSlots < 0) {
        throw new IllegalStateException(
            "TaskTracker reaches negative map slots: " + usedMapSlots);
      }
    } else {
      usedReduceSlots -= numSlots;
      if (usedReduceSlots < 0) {
        throw new IllegalStateException(
            "TaskTracker reaches negative reduce slots: " + usedReduceSlots);
      }
    }
  }

  /**
   * Records that a task attempt has completed. Ignores the event for tasks
   * that got killed after the creation of the completion event.
   *
   * @param event the TaskAttemptCompletionEvent the tracker sent to itself
   * @return the list of response events, empty
   */
  private List<SimulatorEvent> processTaskAttemptCompletionEvent(
      TaskAttemptCompletionEvent event) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Processing task attempt completion event" + event);
    }
   
    long now = event.getTimeStamp()
    TaskStatus finalStatus = event.getStatus();
    TaskAttemptID taskID = finalStatus.getTaskID();
    boolean killedEarlier = orphanTaskCompletions.remove(taskID);
    if (!killedEarlier) {
      finishRunningTask(finalStatus, now);
    }
    return SimulatorEngine.EMPTY_EVENTS;
  }
 
  /**
   * Creates a signal for itself marking the completion of a task attempt.
   * It assumes that the task attempt hasn't made any progress in the user
   * space code so far, i.e. it is called right at launch for map tasks and
   * immediately after all maps completed for reduce tasks.
   *
   * @param tip the simulator task in progress
   * @param now the current simulation time
   * @return the TaskAttemptCompletionEvent we are sending to ourselves
   */
  private TaskAttemptCompletionEvent createTaskAttemptCompletionEvent(
                                       SimulatorTaskInProgress tip, long now) {
    // We need to clone() status as we modify and it goes into an Event
    TaskStatus status = (TaskStatus)tip.getTaskStatus().clone();
    long delta = tip.getUserSpaceRunTime();
    assert delta >= 0 : "TaskAttempt " + tip.getTaskStatus().getTaskID()
        + " has negative UserSpaceRunTime = " + delta;
    long finishTime = now + delta;
    status.setFinishTime(finishTime);
    status.setProgress(1.0f);
    status.setRunState(tip.getFinalRunState());
    TaskAttemptCompletionEvent event =
        new TaskAttemptCompletionEvent(this, status);
    if (LOG.isDebugEnabled()) {
      LOG.debug("Created task attempt completion event " + event);
    }
    return event;
  }
 
  /**
   * Launches a task on the simulated task tracker.
   *
   * @param action SimulatorLaunchTaskAction sent by the job tracker
   * @param now current simulation time
   * @return new events generated, a TaskAttemptCompletionEvent for map
   *         tasks, empty otherwise
   */
  private List<SimulatorEvent> handleSimulatorLaunchTaskAction(
                         SimulatorLaunchTaskAction action, long now) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Handling launch task action " + action);
    }
    // First, create statuses and update used slots for map and reduce
    // task separately
    Task task = action.getTask();
    TaskAttemptID taskId = task.getTaskID();
    if (tasks.containsKey(taskId)) {
      throw new IllegalArgumentException("Multiple launch of task id =" + taskId);
    }

    // Ctor of MapTaskStatus and ReduceTaskStatus need deprecated
    // o.a.h.mapred.TaskAttemptID, hence the downgrade
    org.apache.hadoop.mapred.TaskAttemptID taskIdOldApi =
        org.apache.hadoop.mapred.TaskAttemptID.downgrade(taskId);
    TaskStatus status;
    int numSlotsRequired = task.getNumSlotsRequired();   
    Counters emptyCounters = new Counters();
    if (task.isMapTask()) {    
      status = new MapTaskStatus(taskIdOldApi, 0f, numSlotsRequired,
                                 State.RUNNING, "", "", taskTrackerName,
                                 Phase.MAP, emptyCounters);
      usedMapSlots += numSlotsRequired;
      if (usedMapSlots > maxMapSlots) {
        throw new IllegalStateException("usedMapSlots exceeds maxMapSlots: " +
          usedMapSlots + " > " + maxMapSlots);
      }
    } else {
      status = new ReduceTaskStatus(taskIdOldApi, 0f, numSlotsRequired,
                                    State.RUNNING, "", "", taskTrackerName,
                                    Phase.SHUFFLE, emptyCounters);
      usedReduceSlots += numSlotsRequired;
      if (usedReduceSlots > maxReduceSlots) {
        throw new IllegalStateException("usedReduceSlots exceeds usedReduceSlots: " +
            usedReduceSlots + " > " + usedReduceSlots);
      }
    }
   
    //  Second, create and store a TIP
    status.setStartTime(now);
    SimulatorTaskInProgress tip =
      new SimulatorTaskInProgress(action, status, now);
    tasks.put(taskId, tip);

    // Third, schedule events for ourselves
    if (task.isMapTask()) {
      // we know when this task attempts ends iff it is a map
      TaskAttemptCompletionEvent e = createTaskAttemptCompletionEvent(tip, now);
      return Collections.<SimulatorEvent>singletonList(e);
    } else {
      // reduce, completion time can only be determined when all maps are done
      return SimulatorEngine.EMPTY_EVENTS;
    }
  }
 
  /**
   * Kills a task attempt.
   *
   * @param action contains the task attempt to kill
   * @param now current simulation time
   * @return new events generated in response, empty
   */
  private List<SimulatorEvent> handleKillTaskAction(KillTaskAction action, long now) {
    TaskAttemptID taskId = action.getTaskID();
    // we don't have a nice(r) toString() in Hadoop's TaskActions
    if (LOG.isDebugEnabled()) {
      LOG.debug("Handling kill task action, taskId=" + taskId + ", now=" + now);
    }
   
    SimulatorTaskInProgress tip = tasks.get(taskId);
   
    // Safety check: We might get a KillTaskAction even for completed reduces
    if (tip == null) {
      return SimulatorEngine.EMPTY_EVENTS;
    }
   
    progressTaskStatus(tip, now); // make progress up to date
    TaskStatus finalStatus = (TaskStatus)tip.getTaskStatus().clone();
    finalStatus.setFinishTime(now);
    finalStatus.setRunState(State.KILLED);
    finishRunningTask(finalStatus, now);
  
    if (finalStatus.getIsMap() || finalStatus.getPhase() == Phase.REDUCE) {
      // if we have already created a task attempt completion event we remember
      // the task id, so that we can safely ignore the event when its delivered
      orphanTaskCompletions.add(taskId);
    }
    return SimulatorEngine.EMPTY_EVENTS;
 

  /**
   * Starts "running" the REDUCE phase of reduce upon being notified that
   * all map tasks are (successfully) done.
   *
   * @param action contains the notification for one of the reduce tasks
   * @param now current simulation time
   * @return new events generated, a single TaskAttemptCompletionEvent for the
   *         reduce
   */
  private List<SimulatorEvent> handleAllMapsCompletedTaskAction(
                        AllMapsCompletedTaskAction action, long now) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Handling all maps completed task action " + action);
    }
   
    TaskAttemptID taskId = action.getTaskID();
    SimulatorTaskInProgress tip = tasks.get(taskId);
    // If tip is null here it is because the task attempt to be notified is
    // unknown to this TaskTracker.
    TaskStatus status = tip.getTaskStatus();
    if (status.getIsMap()) {
      throw new IllegalStateException(
          "Invalid AllMapsCompletedTaskAction, task attempt "
              + "to be notified is a map: " + taskId + " " + status);
    }
    if (status.getPhase() != Phase.SHUFFLE) {
      throw new IllegalArgumentException(
          "Reducer task attempt already notified: " + taskId + " " + status);
    }
          
    // Warning: setPhase() uses System.currentTimeMillis() internally to
    // set shuffle and sort times, but we overwrite that manually anyway
    status.setPhase(Phase.REDUCE);
    status.setShuffleFinishTime(now);
    status.setSortFinishTime(now);
   
    // Forecast the completion of this reduce
    TaskAttemptCompletionEvent e = createTaskAttemptCompletionEvent(tip, now);
    return Collections.<SimulatorEvent>singletonList(e);
  }
 
  /**
   * Updates the progress indicator of a task if it is running.
   *
   * @param tip simulator task in progress whose progress is to be updated
   * @param now current simulation time
   */
  private void progressTaskStatus(SimulatorTaskInProgress tip, long now) {
    TaskStatus status = tip.getTaskStatus();
    if (status.getRunState() != State.RUNNING) {
      return; // nothing to be done
    }

    boolean isMap = tip.isMapTask();
    // Time when the user space code started
    long startTime = -1;
    // Time spent in map or just in the REDUCE phase of a reduce task
    long runTime = tip.getUserSpaceRunTime();
    float progress = 0.0f;
    if (isMap) {
      // We linearly estimate the progress of maps since their start
      startTime = status.getStartTime();
      progress = ((float)(now - startTime)) / runTime;
    } else {
      // We don't model reduce progress in the SHUFFLE or SORT phases
      // We use linear estimate for the 3rd, REDUCE phase
      Phase reducePhase = status.getPhase();
      switch (reducePhase) {
      case SHUFFLE:
        progress = 0.0f; // 0 phase is done out of 3
        break;
      case SORT:
        progress = 1.0f/3; // 1 phase is done out of 3
        break;
      case REDUCE: {
        // REDUCE phase with the user code started when sort finished
        startTime = status.getSortFinishTime();
        // 0.66f : 2 phases are done out of of 3
        progress = 2.0f/3 + (((float) (now - startTime)) / runTime) / 3.0f;
      }
        break;
      default:
        // should never get here
        throw new IllegalArgumentException("Invalid reducePhase=" + reducePhase);
      }
    }
   
    final float EPSILON = 0.0001f;
    if (progress < -EPSILON || progress > 1 + EPSILON) {
      throw new IllegalStateException("Task progress out of range: " + progress);
    }
    progress = Math.max(Math.min(1.0f, progress), 0.0f);
    status.setProgress(progress);
   
    if (LOG.isDebugEnabled()) {
      LOG.debug("Updated task progress, taskId=" + status.getTaskID()
          + ", progress=" + status.getProgress());
    }
  }
 
  /**
   * Updates the progress indicator of all running tasks.
   *
   * @param now current simulation time
   */
  private void progressTaskStatuses(long now) {
    for (SimulatorTaskInProgress tip : tasks.values()) {
      progressTaskStatus(tip, now);
    }
  }

  /**
   * Frees up bookkeping memory used by completed tasks.
   * Has no effect on the events or logs produced by the SimulatorTaskTracker.
   * We need this in order not to report completed task multiple times and
   * to ensure that we do not run out of Java heap memory in larger
   * simulations.
   */
  private void garbageCollectCompletedTasks() {
    for (Iterator<TaskAttemptID> iter = tasks.keySet().iterator();
         iter.hasNext();) {
      TaskAttemptID taskId = iter.next();
      SimulatorTaskInProgress tip = tasks.get(taskId);
      if (tip.getTaskStatus().getRunState() != State.RUNNING) {
        iter.remove();
        if (LOG.isDebugEnabled()) {
          LOG.debug("Garbage collected SimulatorTIP, taskId=" + taskId);
        }
        // We don't have to / must not touch usedMapSlots and usedReduceSlots
        // as those were already updated by processTaskAttemptCompletionEvent()
        // when the task switched its state from running
      }
    }
  }
 
  /**
   * Creates a list of task statuses suitable for transmission via heartbeat().
   * The task statuses are cloned() so that the heartbeat() callee, the job
   * tracker, can't mess up the SimulatorTaskTracker's internal data.
   *
   * @return the list of running and recently completed task statuses
   * on the tracker
   */
  private List<TaskStatus> collectAndCloneTaskStatuses() {
    ArrayList<TaskStatus> statuses = new ArrayList<TaskStatus>();
    for (SimulatorTaskInProgress tip : tasks.values()) {
      statuses.add((TaskStatus)tip.getTaskStatus().clone());
    }
    return statuses;
  }

  /**
   * Handles the HeartbeatResponse received from the job tracker upon
   * heartbeat(). Dispatches to handle*Action() methods.
   *
   * @param response HeartbeatResponse received from the job tracker
   * @param now current simulation time
   * @return list of new events generated in response to the task actions
   */
  private List<SimulatorEvent> handleHeartbeatResponse(HeartbeatResponse response,
                                              long now) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Handling heartbeat response " + response);
    }

    List<SimulatorEvent> events = new ArrayList<SimulatorEvent>()
    TaskTrackerAction[] actions = response.getActions();
    for (TaskTrackerAction action : actions) {
      List<SimulatorEvent> actionEvents;
      if (action instanceof SimulatorLaunchTaskAction) {
        actionEvents = handleSimulatorLaunchTaskAction(
            (SimulatorLaunchTaskAction)action, now);           
      } else if(action instanceof KillTaskAction) {
        actionEvents = handleKillTaskAction((KillTaskAction)action, now);
      } else if(action instanceof AllMapsCompletedTaskAction) {
        // our extra task action for notifying the reducers
        actionEvents = handleAllMapsCompletedTaskAction(
            (AllMapsCompletedTaskAction)action, now);
      } else {
        // Should never get here.
        // CommitTaskAction is not implemented in the simulator
        // LaunchTaskAction has to be SimulatorLaunchTaskAction
        throw new UnsupportedOperationException("Unimplemented TaskAction: "
            + action);
      }
      events.addAll(actionEvents);
    }
    return events;
  }
 
  /**
   * Transmits a heartbeat event to the jobtracker and processes the response.
   *
   * @param event HeartbeatEvent to process
   * @return list of new events generated in response
   */
  private List<SimulatorEvent> processHeartbeatEvent(HeartbeatEvent event) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("Processing heartbeat event " + event);
    }
   
    long now = event.getTimeStamp();
   
    // Create the TaskTrackerStatus to report
    progressTaskStatuses(now);
    List<TaskStatus> taskStatuses = collectAndCloneTaskStatuses();
    boolean askForNewTask = (usedMapSlots < maxMapSlots ||
                             usedReduceSlots < maxReduceSlots);

    // 0 means failures == 0 here. Undocumented in TaskTracker, but does not
    // seem to be used at all in org.apache.hadoop.mapred .
    TaskTrackerStatus taskTrackerStatus =
      new SimulatorTaskTrackerStatus(taskTrackerName, hostName, httpPort,
          taskStatuses, 0,
          maxMapSlots, maxReduceSlots, now);
   
    // This is the right, and only, place to release bookkeping memory held
    // by completed tasks: after collectAndCloneTaskStatuses() and before
    // heartbeat().
    // The status of TIPs to be purged is already cloned & copied to
    // taskStatuses for reporting
    // We shouldn't run the gc after heartbeat() since  KillTaskAction might
    // produce new completed tasks that we have not yet reported back and
    // don't want to purge immediately.
    garbageCollectCompletedTasks();
   
    // Transmit the heartbeat
    HeartbeatResponse response = null;
    try {
      response =
        jobTracker.heartbeat(taskTrackerStatus, false, firstHeartbeat,
                             askForNewTask, heartbeatResponseId);
    } catch (IOException ioe) {
      throw new IllegalStateException("Internal error", ioe);
    }
    firstHeartbeat = false;

    // The heartbeat got through successfully!
    heartbeatResponseId = response.getResponseId();

    // Process the heartbeat response
    List<SimulatorEvent> events = handleHeartbeatResponse(response, now);
   
    // Next heartbeat
    events.add(new HeartbeatEvent(this, now + response.getHeartbeatInterval()));

    return events;
  }
 
  /**
   * Internal helper class used for storing the current status and other
   * auxilliary information associated with a task attempt assigned to
   * a simulator task tracker.
   * WARNING: This is a completely different inner class than the one with
   *          the same name in SimulatorJobTracker.
   */
  static class SimulatorTaskInProgress {
 
    /**
     * Current status of the task attempt.
     * We store the start time, the start time of reduce phases and the
     * run state of the task in this object.
     */
    private TaskStatus taskStatus;
   
    /**
     * Object storing the run time and the final state of the task attempt.
     * It is never read directly by the SimulatorTaskTracker.
     */
    private TaskAttemptInfo taskAttempInfo;

    /**
     * Runtime of the user-space code of the task attempt. This is the full
     * runtime for map tasks, and only that of the REDUCE phase for reduce
     * tasks.
     */
    private final long userSpaceRunTime;
   
    /**
     * Constructs an object by copying most of the fields from a
     * SimulatorTaskAction.
     */
    public SimulatorTaskInProgress(SimulatorLaunchTaskAction action,
                                   TaskStatus taskStatus, long now) {
      this.taskStatus = taskStatus;
      this.taskAttempInfo = action.getTaskAttemptInfo();
      if (taskStatus.getIsMap()) {
        this.userSpaceRunTime = taskAttempInfo.getRuntime();
      } else {
        this.userSpaceRunTime =
          ((ReduceTaskAttemptInfo)taskAttempInfo).getReduceRuntime();
      }
    }
   
    /**
     * Returns whether the task attempt is a map.
     *
     * @return true iff the task attempt is a map
     */
    public boolean isMapTask() {
      return taskStatus.getIsMap();
    }

    /*
     * Returns the current status of the task attempt.
     *
     * @return current task status
     */
    public TaskStatus getTaskStatus() {
      return taskStatus;
    }
   
    /**
     * Sets the status of the task attempt.
     *
     * @param status the new task status
     */
    public void setTaskStatus(TaskStatus status) {
      this.taskStatus = status;
    }
       
    /**
     * Returns the final state of the completed task.
     *
     * @return the final state of the completed task;
     *        it is either State.SUCCEEDED or State.FAILED
     */
    public State getFinalRunState() {
      return taskAttempInfo.getRunState();
    }
   
    /**
     * Gets the time spent in the user space code of the task attempt.
     * This is the full runtime for map tasks, and only that of the REDUCE
     * phase for reduce tasks.
     *
     * @return the user space runtime
     */
    public long getUserSpaceRunTime() {
      return userSpaceRunTime;
    }         
  }
}
TOP

Related Classes of org.apache.hadoop.mapred.SimulatorTaskTracker$SimulatorTaskInProgress

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.