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 package org.apache.hadoop.mapreduce;
019
020 import java.io.DataInput;
021 import java.io.DataOutput;
022 import java.io.IOException;
023 import java.util.HashMap;
024 import java.util.Map;
025 import java.util.Map.Entry;
026
027 import org.apache.hadoop.classification.InterfaceAudience;
028 import org.apache.hadoop.classification.InterfaceStability;
029 import org.apache.hadoop.io.Text;
030 import org.apache.hadoop.io.Writable;
031 import org.apache.hadoop.io.WritableFactories;
032 import org.apache.hadoop.io.WritableFactory;
033 import org.apache.hadoop.io.WritableUtils;
034 import org.apache.hadoop.security.authorize.AccessControlList;
035 import org.apache.hadoop.util.StringInterner;
036
037 /**************************************************
038 * Describes the current status of a job.
039 **************************************************/
040 @InterfaceAudience.Public
041 @InterfaceStability.Evolving
042 public class JobStatus implements Writable, Cloneable {
043
044 static { // register a ctor
045 WritableFactories.setFactory
046 (JobStatus.class,
047 new WritableFactory() {
048 public Writable newInstance() { return new JobStatus(); }
049 });
050 }
051
052 /**
053 * Current state of the job
054 */
055 public static enum State {
056 RUNNING(1),
057 SUCCEEDED(2),
058 FAILED(3),
059 PREP(4),
060 KILLED(5);
061
062 int value;
063
064 State(int value) {
065 this.value = value;
066 }
067
068 public int getValue() {
069 return value;
070 }
071
072 };
073
074 private JobID jobid;
075 private float mapProgress;
076 private float reduceProgress;
077 private float cleanupProgress;
078 private float setupProgress;
079 private State runState;
080 private long startTime;
081 private String user;
082 private String queue;
083 private JobPriority priority;
084 private String schedulingInfo="NA";
085 private String failureInfo = "NA";
086
087 private Map<JobACL, AccessControlList> jobACLs =
088 new HashMap<JobACL, AccessControlList>();
089
090 private String jobName;
091 private String jobFile;
092 private long finishTime;
093 private boolean isRetired;
094 private String historyFile = "";
095 private String trackingUrl ="";
096 private int numUsedSlots;
097 private int numReservedSlots;
098 private int usedMem;
099 private int reservedMem;
100 private int neededMem;
101 private boolean isUber;
102
103 /**
104 */
105 public JobStatus() {
106 }
107
108 /**
109 * Create a job status object for a given jobid.
110 * @param jobid The jobid of the job
111 * @param setupProgress The progress made on the setup
112 * @param mapProgress The progress made on the maps
113 * @param reduceProgress The progress made on the reduces
114 * @param cleanupProgress The progress made on the cleanup
115 * @param runState The current state of the job
116 * @param jp Priority of the job.
117 * @param user userid of the person who submitted the job.
118 * @param jobName user-specified job name.
119 * @param jobFile job configuration file.
120 * @param trackingUrl link to the web-ui for details of the job.
121 */
122 public JobStatus(JobID jobid, float setupProgress, float mapProgress,
123 float reduceProgress, float cleanupProgress,
124 State runState, JobPriority jp, String user, String jobName,
125 String jobFile, String trackingUrl) {
126 this(jobid, setupProgress, mapProgress, reduceProgress, cleanupProgress,
127 runState, jp, user, jobName, "default", jobFile, trackingUrl, false);
128 }
129
130 /**
131 * Create a job status object for a given jobid.
132 * @param jobid The jobid of the job
133 * @param setupProgress The progress made on the setup
134 * @param mapProgress The progress made on the maps
135 * @param reduceProgress The progress made on the reduces
136 * @param cleanupProgress The progress made on the cleanup
137 * @param runState The current state of the job
138 * @param jp Priority of the job.
139 * @param user userid of the person who submitted the job.
140 * @param jobName user-specified job name.
141 * @param queue queue name
142 * @param jobFile job configuration file.
143 * @param trackingUrl link to the web-ui for details of the job.
144 */
145 public JobStatus(JobID jobid, float setupProgress, float mapProgress,
146 float reduceProgress, float cleanupProgress,
147 State runState, JobPriority jp,
148 String user, String jobName, String queue,
149 String jobFile, String trackingUrl) {
150 this(jobid, setupProgress, mapProgress, reduceProgress, cleanupProgress,
151 runState, jp, user, jobName, queue, jobFile, trackingUrl, false);
152 }
153
154 /**
155 * Create a job status object for a given jobid.
156 * @param jobid The jobid of the job
157 * @param setupProgress The progress made on the setup
158 * @param mapProgress The progress made on the maps
159 * @param reduceProgress The progress made on the reduces
160 * @param cleanupProgress The progress made on the cleanup
161 * @param runState The current state of the job
162 * @param jp Priority of the job.
163 * @param user userid of the person who submitted the job.
164 * @param jobName user-specified job name.
165 * @param queue queue name
166 * @param jobFile job configuration file.
167 * @param trackingUrl link to the web-ui for details of the job.
168 * @param isUber Whether job running in uber mode
169 */
170 public JobStatus(JobID jobid, float setupProgress, float mapProgress,
171 float reduceProgress, float cleanupProgress,
172 State runState, JobPriority jp,
173 String user, String jobName, String queue,
174 String jobFile, String trackingUrl, boolean isUber) {
175 this.jobid = jobid;
176 this.setupProgress = setupProgress;
177 this.mapProgress = mapProgress;
178 this.reduceProgress = reduceProgress;
179 this.cleanupProgress = cleanupProgress;
180 this.runState = runState;
181 this.user = user;
182 this.queue = queue;
183 if (jp == null) {
184 throw new IllegalArgumentException("Job Priority cannot be null.");
185 }
186 priority = jp;
187 this.jobName = jobName;
188 this.jobFile = jobFile;
189 this.trackingUrl = trackingUrl;
190 this.isUber = isUber;
191 }
192
193
194 /**
195 * Sets the map progress of this job
196 * @param p The value of map progress to set to
197 */
198 protected synchronized void setMapProgress(float p) {
199 this.mapProgress = (float) Math.min(1.0, Math.max(0.0, p));
200 }
201
202 /**
203 * Sets the cleanup progress of this job
204 * @param p The value of cleanup progress to set to
205 */
206 protected synchronized void setCleanupProgress(float p) {
207 this.cleanupProgress = (float) Math.min(1.0, Math.max(0.0, p));
208 }
209
210 /**
211 * Sets the setup progress of this job
212 * @param p The value of setup progress to set to
213 */
214 protected synchronized void setSetupProgress(float p) {
215 this.setupProgress = (float) Math.min(1.0, Math.max(0.0, p));
216 }
217
218 /**
219 * Sets the reduce progress of this Job
220 * @param p The value of reduce progress to set to
221 */
222 protected synchronized void setReduceProgress(float p) {
223 this.reduceProgress = (float) Math.min(1.0, Math.max(0.0, p));
224 }
225
226 /**
227 * Set the priority of the job, defaulting to NORMAL.
228 * @param jp new job priority
229 */
230 protected synchronized void setPriority(JobPriority jp) {
231 if (jp == null) {
232 throw new IllegalArgumentException("Job priority cannot be null.");
233 }
234 priority = jp;
235 }
236
237 /**
238 * Set the finish time of the job
239 * @param finishTime The finishTime of the job
240 */
241 protected synchronized void setFinishTime(long finishTime) {
242 this.finishTime = finishTime;
243 }
244
245 /**
246 * Set the job history file url for a completed job
247 */
248 protected synchronized void setHistoryFile(String historyFile) {
249 this.historyFile = historyFile;
250 }
251
252 /**
253 * Set the link to the web-ui for details of the job.
254 */
255 protected synchronized void setTrackingUrl(String trackingUrl) {
256 this.trackingUrl = trackingUrl;
257 }
258
259 /**
260 * Set the job retire flag to true.
261 */
262 protected synchronized void setRetired() {
263 this.isRetired = true;
264 }
265
266 /**
267 * Change the current run state of the job.
268 */
269 protected synchronized void setState(State state) {
270 this.runState = state;
271 }
272
273 /**
274 * Set the start time of the job
275 * @param startTime The startTime of the job
276 */
277 protected synchronized void setStartTime(long startTime) {
278 this.startTime = startTime;
279 }
280
281 /**
282 * @param userName The username of the job
283 */
284 protected synchronized void setUsername(String userName) {
285 this.user = userName;
286 }
287
288 /**
289 * Used to set the scheduling information associated to a particular Job.
290 *
291 * @param schedulingInfo Scheduling information of the job
292 */
293 protected synchronized void setSchedulingInfo(String schedulingInfo) {
294 this.schedulingInfo = schedulingInfo;
295 }
296
297 /**
298 * Set the job acls.
299 *
300 * @param acls {@link Map} from {@link JobACL} to {@link AccessControlList}
301 */
302 protected synchronized void setJobACLs(Map<JobACL, AccessControlList> acls) {
303 this.jobACLs = acls;
304 }
305
306 /**
307 * Set queue name
308 * @param queue queue name
309 */
310 protected synchronized void setQueue(String queue) {
311 this.queue = queue;
312 }
313
314 /**
315 * Set diagnostic information.
316 * @param failureInfo diagnostic information
317 */
318 protected synchronized void setFailureInfo(String failureInfo) {
319 this.failureInfo = failureInfo;
320 }
321
322 /**
323 * Get queue name
324 * @return queue name
325 */
326 public synchronized String getQueue() {
327 return queue;
328 }
329
330 /**
331 * @return Percentage of progress in maps
332 */
333 public synchronized float getMapProgress() { return mapProgress; }
334
335 /**
336 * @return Percentage of progress in cleanup
337 */
338 public synchronized float getCleanupProgress() { return cleanupProgress; }
339
340 /**
341 * @return Percentage of progress in setup
342 */
343 public synchronized float getSetupProgress() { return setupProgress; }
344
345 /**
346 * @return Percentage of progress in reduce
347 */
348 public synchronized float getReduceProgress() { return reduceProgress; }
349
350 /**
351 * @return running state of the job
352 */
353 public synchronized State getState() { return runState; }
354
355 /**
356 * @return start time of the job
357 */
358 synchronized public long getStartTime() { return startTime;}
359
360 @Override
361 public Object clone() {
362 try {
363 return super.clone();
364 } catch (CloneNotSupportedException cnse) {
365 // Shouldn't happen since we do implement Clonable
366 throw new InternalError(cnse.toString());
367 }
368 }
369
370 /**
371 * @return The jobid of the Job
372 */
373 public JobID getJobID() { return jobid; }
374
375 /**
376 * @return the username of the job
377 */
378 public synchronized String getUsername() { return this.user;}
379
380 /**
381 * Gets the Scheduling information associated to a particular Job.
382 * @return the scheduling information of the job
383 */
384 public synchronized String getSchedulingInfo() {
385 return schedulingInfo;
386 }
387
388 /**
389 * Get the job acls.
390 *
391 * @return a {@link Map} from {@link JobACL} to {@link AccessControlList}
392 */
393 public synchronized Map<JobACL, AccessControlList> getJobACLs() {
394 return jobACLs;
395 }
396
397 /**
398 * Return the priority of the job
399 * @return job priority
400 */
401 public synchronized JobPriority getPriority() { return priority; }
402
403 /**
404 * Gets any available info on the reason of failure of the job.
405 * @return diagnostic information on why a job might have failed.
406 */
407 public synchronized String getFailureInfo() {
408 return this.failureInfo;
409 }
410
411
412 /**
413 * Returns true if the status is for a completed job.
414 */
415 public synchronized boolean isJobComplete() {
416 return (runState == JobStatus.State.SUCCEEDED ||
417 runState == JobStatus.State.FAILED ||
418 runState == JobStatus.State.KILLED);
419 }
420
421 ///////////////////////////////////////
422 // Writable
423 ///////////////////////////////////////
424 public synchronized void write(DataOutput out) throws IOException {
425 jobid.write(out);
426 out.writeFloat(setupProgress);
427 out.writeFloat(mapProgress);
428 out.writeFloat(reduceProgress);
429 out.writeFloat(cleanupProgress);
430 WritableUtils.writeEnum(out, runState);
431 out.writeLong(startTime);
432 Text.writeString(out, user);
433 WritableUtils.writeEnum(out, priority);
434 Text.writeString(out, schedulingInfo);
435 out.writeLong(finishTime);
436 out.writeBoolean(isRetired);
437 Text.writeString(out, historyFile);
438 Text.writeString(out, jobName);
439 Text.writeString(out, trackingUrl);
440 Text.writeString(out, jobFile);
441 out.writeBoolean(isUber);
442
443 // Serialize the job's ACLs
444 out.writeInt(jobACLs.size());
445 for (Entry<JobACL, AccessControlList> entry : jobACLs.entrySet()) {
446 WritableUtils.writeEnum(out, entry.getKey());
447 entry.getValue().write(out);
448 }
449 }
450
451 public synchronized void readFields(DataInput in) throws IOException {
452 this.jobid = new JobID();
453 this.jobid.readFields(in);
454 this.setupProgress = in.readFloat();
455 this.mapProgress = in.readFloat();
456 this.reduceProgress = in.readFloat();
457 this.cleanupProgress = in.readFloat();
458 this.runState = WritableUtils.readEnum(in, State.class);
459 this.startTime = in.readLong();
460 this.user = StringInterner.weakIntern(Text.readString(in));
461 this.priority = WritableUtils.readEnum(in, JobPriority.class);
462 this.schedulingInfo = StringInterner.weakIntern(Text.readString(in));
463 this.finishTime = in.readLong();
464 this.isRetired = in.readBoolean();
465 this.historyFile = StringInterner.weakIntern(Text.readString(in));
466 this.jobName = StringInterner.weakIntern(Text.readString(in));
467 this.trackingUrl = StringInterner.weakIntern(Text.readString(in));
468 this.jobFile = StringInterner.weakIntern(Text.readString(in));
469 this.isUber = in.readBoolean();
470
471 // De-serialize the job's ACLs
472 int numACLs = in.readInt();
473 for (int i = 0; i < numACLs; i++) {
474 JobACL aclType = WritableUtils.readEnum(in, JobACL.class);
475 AccessControlList acl = new AccessControlList(" ");
476 acl.readFields(in);
477 this.jobACLs.put(aclType, acl);
478 }
479 }
480
481 /**
482 * Get the user-specified job name.
483 */
484 public String getJobName() {
485 return jobName;
486 }
487
488 /**
489 * Get the configuration file for the job.
490 */
491 public String getJobFile() {
492 return jobFile;
493 }
494
495 /**
496 * Get the link to the web-ui for details of the job.
497 */
498 public synchronized String getTrackingUrl() {
499 return trackingUrl;
500 }
501
502 /**
503 * Get the finish time of the job.
504 */
505 public synchronized long getFinishTime() {
506 return finishTime;
507 }
508
509 /**
510 * Check whether the job has retired.
511 */
512 public synchronized boolean isRetired() {
513 return isRetired;
514 }
515
516 /**
517 * @return the job history file name for a completed job. If job is not
518 * completed or history file not available then return null.
519 */
520 public synchronized String getHistoryFile() {
521 return historyFile;
522 }
523
524 /**
525 * @return number of used mapred slots
526 */
527 public int getNumUsedSlots() {
528 return numUsedSlots;
529 }
530
531 /**
532 * @param n number of used mapred slots
533 */
534 public void setNumUsedSlots(int n) {
535 numUsedSlots = n;
536 }
537
538 /**
539 * @return the number of reserved slots
540 */
541 public int getNumReservedSlots() {
542 return numReservedSlots;
543 }
544
545 /**
546 * @param n the number of reserved slots
547 */
548 public void setNumReservedSlots(int n) {
549 this.numReservedSlots = n;
550 }
551
552 /**
553 * @return the used memory
554 */
555 public int getUsedMem() {
556 return usedMem;
557 }
558
559 /**
560 * @param m the used memory
561 */
562 public void setUsedMem(int m) {
563 this.usedMem = m;
564 }
565
566 /**
567 * @return the reserved memory
568 */
569 public int getReservedMem() {
570 return reservedMem;
571 }
572
573 /**
574 * @param r the reserved memory
575 */
576 public void setReservedMem(int r) {
577 this.reservedMem = r;
578 }
579
580 /**
581 * @return the needed memory
582 */
583 public int getNeededMem() {
584 return neededMem;
585 }
586
587 /**
588 * @param n the needed memory
589 */
590 public void setNeededMem(int n) {
591 this.neededMem = n;
592 }
593
594 /**
595 * Whether job running in uber mode
596 * @return job in uber-mode
597 */
598 public synchronized boolean isUber() {
599 return isUber;
600 }
601
602 /**
603 * Set uber-mode flag
604 * @param isUber Whether job running in uber-mode
605 */
606 public synchronized void setUber(boolean isUber) {
607 this.isUber = isUber;
608 }
609
610 public String toString() {
611 StringBuffer buffer = new StringBuffer();
612 buffer.append("job-id : " + jobid);
613 buffer.append("uber-mode : " + isUber);
614 buffer.append("map-progress : " + mapProgress);
615 buffer.append("reduce-progress : " + reduceProgress);
616 buffer.append("cleanup-progress : " + cleanupProgress);
617 buffer.append("setup-progress : " + setupProgress);
618 buffer.append("runstate : " + runState);
619 buffer.append("start-time : " + startTime);
620 buffer.append("user-name : " + user);
621 buffer.append("priority : " + priority);
622 buffer.append("scheduling-info : " + schedulingInfo);
623 buffer.append("num-used-slots" + numUsedSlots);
624 buffer.append("num-reserved-slots" + numReservedSlots);
625 buffer.append("used-mem" + usedMem);
626 buffer.append("reserved-mem" + reservedMem);
627 buffer.append("needed-mem" + neededMem);
628 return buffer.toString();
629 }
630 }