001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    
019    package org.apache.hadoop.mapreduce;
020    
021    import java.io.DataInput;
022    import java.io.DataOutput;
023    import java.io.IOException;
024    
025    import org.apache.hadoop.classification.InterfaceAudience;
026    import org.apache.hadoop.classification.InterfaceStability;
027    import org.apache.hadoop.io.Writable;
028    import org.apache.hadoop.io.WritableUtils;
029    
030    /**
031     * This is used to track task completion events on 
032     * job tracker. 
033     */
034    @InterfaceAudience.Public
035    @InterfaceStability.Evolving
036    public class TaskCompletionEvent implements Writable{
037      @InterfaceAudience.Public
038      @InterfaceStability.Evolving
039      static public enum Status {FAILED, KILLED, SUCCEEDED, OBSOLETE, TIPFAILED};
040        
041      private int eventId; 
042      private String taskTrackerHttp;
043      private int taskRunTime; // using int since runtime is the time difference
044      private TaskAttemptID taskId;
045      Status status; 
046      boolean isMap = false;
047      private int idWithinJob;
048      public static final TaskCompletionEvent[] EMPTY_ARRAY = 
049        new TaskCompletionEvent[0];
050      /**
051       * Default constructor for Writable.
052       *
053       */
054      public TaskCompletionEvent(){
055        taskId = new TaskAttemptID();
056      }
057    
058      /**
059       * Constructor. eventId should be created externally and incremented
060       * per event for each job. 
061       * @param eventId event id, event id should be unique and assigned in
062       *  incrementally, starting from 0. 
063       * @param taskId task id
064       * @param status task's status 
065       * @param taskTrackerHttp task tracker's host:port for http. 
066       */
067      public TaskCompletionEvent(int eventId, 
068                                 TaskAttemptID taskId,
069                                 int idWithinJob,
070                                 boolean isMap,
071                                 Status status, 
072                                 String taskTrackerHttp){
073          
074        this.taskId = taskId;
075        this.idWithinJob = idWithinJob;
076        this.isMap = isMap;
077        this.eventId = eventId; 
078        this.status =status; 
079        this.taskTrackerHttp = taskTrackerHttp;
080      }
081      /**
082       * Returns event Id. 
083       * @return event id
084       */
085      public int getEventId() {
086        return eventId;
087      }
088      
089      /**
090       * Returns task id. 
091       * @return task id
092       */
093      public TaskAttemptID getTaskAttemptId() {
094        return taskId;
095      }
096      
097      /**
098       * Returns {@link Status}
099       * @return task completion status
100       */
101      public Status getStatus() {
102        return status;
103      }
104      /**
105       * http location of the tasktracker where this task ran. 
106       * @return http location of tasktracker user logs
107       */
108      public String getTaskTrackerHttp() {
109        return taskTrackerHttp;
110      }
111    
112      /**
113       * Returns time (in millisec) the task took to complete. 
114       */
115      public int getTaskRunTime() {
116        return taskRunTime;
117      }
118    
119      /**
120       * Set the task completion time
121       * @param taskCompletionTime time (in millisec) the task took to complete
122       */
123      protected void setTaskRunTime(int taskCompletionTime) {
124        this.taskRunTime = taskCompletionTime;
125      }
126    
127      /**
128       * set event Id. should be assigned incrementally starting from 0. 
129       * @param eventId
130       */
131      protected void setEventId(int eventId) {
132        this.eventId = eventId;
133      }
134    
135      /**
136       * Sets task id. 
137       * @param taskId
138       */
139      protected void setTaskAttemptId(TaskAttemptID taskId) {
140        this.taskId = taskId;
141      }
142      
143      /**
144       * Set task status. 
145       * @param status
146       */
147      protected void setTaskStatus(Status status) {
148        this.status = status;
149      }
150      
151      /**
152       * Set task tracker http location. 
153       * @param taskTrackerHttp
154       */
155      protected void setTaskTrackerHttp(String taskTrackerHttp) {
156        this.taskTrackerHttp = taskTrackerHttp;
157      }
158        
159      @Override
160      public String toString(){
161        StringBuffer buf = new StringBuffer(); 
162        buf.append("Task Id : "); 
163        buf.append(taskId); 
164        buf.append(", Status : ");  
165        buf.append(status.name());
166        return buf.toString();
167      }
168        
169      @Override
170      public boolean equals(Object o) {
171        if(o == null)
172          return false;
173        if(o.getClass().equals(this.getClass())) {
174          TaskCompletionEvent event = (TaskCompletionEvent) o;
175          return this.isMap == event.isMapTask() 
176                 && this.eventId == event.getEventId()
177                 && this.idWithinJob == event.idWithinJob() 
178                 && this.status.equals(event.getStatus())
179                 && this.taskId.equals(event.getTaskAttemptId()) 
180                 && this.taskRunTime == event.getTaskRunTime()
181                 && this.taskTrackerHttp.equals(event.getTaskTrackerHttp());
182        }
183        return false;
184      }
185    
186      @Override
187      public int hashCode() {
188        return toString().hashCode(); 
189      }
190    
191      public boolean isMapTask() {
192        return isMap;
193      }
194        
195      public int idWithinJob() {
196        return idWithinJob;
197      }
198      //////////////////////////////////////////////
199      // Writable
200      //////////////////////////////////////////////
201      public void write(DataOutput out) throws IOException {
202        taskId.write(out); 
203        WritableUtils.writeVInt(out, idWithinJob);
204        out.writeBoolean(isMap);
205        WritableUtils.writeEnum(out, status); 
206        WritableUtils.writeString(out, taskTrackerHttp);
207        WritableUtils.writeVInt(out, taskRunTime);
208        WritableUtils.writeVInt(out, eventId);
209      }
210      
211      public void readFields(DataInput in) throws IOException {
212        taskId.readFields(in); 
213        idWithinJob = WritableUtils.readVInt(in);
214        isMap = in.readBoolean();
215        status = WritableUtils.readEnum(in, Status.class);
216        taskTrackerHttp = WritableUtils.readString(in);
217        taskRunTime = WritableUtils.readVInt(in);
218        eventId = WritableUtils.readVInt(in);
219      }
220    }