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 }