You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mapreduce-commits@hadoop.apache.org by ac...@apache.org on 2011/03/17 21:21:54 UTC
svn commit: r1082677 [7/38] - in /hadoop/mapreduce/branches/MR-279: ./
assembly/ ivy/ mr-client/ mr-client/hadoop-mapreduce-client-app/
mr-client/hadoop-mapreduce-client-app/src/
mr-client/hadoop-mapreduce-client-app/src/main/ mr-client/hadoop-mapreduc...
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/speculate/StartEndTimesBase.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/speculate/StartEndTimesBase.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/speculate/StartEndTimesBase.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/speculate/StartEndTimesBase.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,211 @@
+/**
+* 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.mapreduce.v2.app.speculate;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.mapreduce.MRJobConfig;
+import org.apache.hadoop.mapreduce.v2.app.AppContext;
+import org.apache.hadoop.mapreduce.v2.app.job.Job;
+import org.apache.hadoop.mapreduce.v2.app.job.Task;
+import org.apache.hadoop.mapreduce.v2.app.job.event.TaskAttemptStatusUpdateEvent.TaskAttemptStatus;
+import org.apache.hadoop.mapreduce.v2.api.JobID;
+import org.apache.hadoop.mapreduce.v2.api.TaskAttemptID;
+import org.apache.hadoop.mapreduce.v2.api.TaskAttemptState;
+import org.apache.hadoop.mapreduce.v2.api.TaskID;
+import org.apache.hadoop.mapreduce.v2.api.TaskType;
+
+abstract class StartEndTimesBase implements TaskRuntimeEstimator {
+ static final float MINIMUM_COMPLETE_PROPORTION_TO_SPECULATE
+ = 0.05F;
+ static final int MINIMUM_COMPLETE_NUMBER_TO_SPECULATE
+ = 10;
+
+ protected Configuration conf = null;
+ protected AppContext context = null;
+
+ protected final Map<TaskAttemptID, Long> startTimes
+ = new ConcurrentHashMap<TaskAttemptID, Long>();
+
+ // XXXX This class design assumes that the contents of AppContext.getAllJobs
+ // never changes. Is that right?
+ //
+ // This assumption comes in in several places, mostly in data structure that
+ // can grow without limit if a AppContext gets new Job's when the old ones
+ // run out. Also, these mapper statistics blocks won't cover the Job's
+ // we don't know about.
+ protected final Map<Job, DataStatistics> mapperStatistics
+ = new HashMap<Job, DataStatistics>();
+ protected final Map<Job, DataStatistics> reducerStatistics
+ = new HashMap<Job, DataStatistics>();
+
+
+ private final Map<Job, Float> slowTaskRelativeTresholds
+ = new HashMap<Job, Float>();
+
+ protected final Set<Task> doneTasks = new HashSet<Task>();
+
+ @Override
+ public void enrollAttempt(TaskAttemptStatus status, long timestamp) {
+ startTimes.put(status.id,timestamp);
+ }
+
+ @Override
+ public long attemptEnrolledTime(TaskAttemptID attemptID) {
+ Long result = startTimes.get(attemptID);
+
+ return result == null ? Long.MAX_VALUE : result;
+ }
+
+
+ @Override
+ public void contextualize(Configuration conf, AppContext context) {
+ this.conf = conf;
+ this.context = context;
+
+ Map<JobID, Job> allJobs = context.getAllJobs();
+
+ for (JobID jobID : allJobs.keySet()) {
+ final Job job = allJobs.get(jobID);
+ mapperStatistics.put(job, new DataStatistics());
+ reducerStatistics.put(job, new DataStatistics());
+ slowTaskRelativeTresholds.put
+ (job, conf.getFloat(MRJobConfig.SPECULATIVE_SLOWTASK_THRESHOLD,1.0f));
+ }
+ }
+
+ protected DataStatistics dataStatisticsForTask(TaskID taskID) {
+ JobID jobID = taskID.jobID;
+ Job job = context.getJob(jobID);
+
+ if (job == null) {
+ return null;
+ }
+
+ Task task = job.getTask(taskID);
+
+ if (task == null) {
+ return null;
+ }
+
+ return task.getType() == TaskType.MAP
+ ? mapperStatistics.get(job)
+ : task.getType() == TaskType.REDUCE
+ ? reducerStatistics.get(job)
+ : null;
+ }
+
+ @Override
+ public long thresholdRuntime(TaskID taskID) {
+ JobID jobID = taskID.jobID;
+ Job job = context.getJob(jobID);
+
+ TaskType type = taskID.taskType;
+
+ DataStatistics statistics
+ = dataStatisticsForTask(taskID);
+
+ int completedTasksOfType
+ = type == TaskType.MAP
+ ? job.getCompletedMaps() : job.getCompletedReduces();
+
+ int totalTasksOfType
+ = type == TaskType.MAP
+ ? job.getTotalMaps() : job.getTotalReduces();
+
+ if (completedTasksOfType < MINIMUM_COMPLETE_NUMBER_TO_SPECULATE
+ || (((float)completedTasksOfType) / totalTasksOfType)
+ < MINIMUM_COMPLETE_PROPORTION_TO_SPECULATE ) {
+ return Long.MAX_VALUE;
+ }
+
+ long result = statistics == null
+ ? Long.MAX_VALUE
+ : (long)statistics.outlier(slowTaskRelativeTresholds.get(job));
+
+ return result;
+ }
+
+ @Override
+ public long estimatedNewAttemptRuntime(TaskID id) {
+ DataStatistics statistics = dataStatisticsForTask(id);
+
+ if (statistics == null) {
+ return -1L;
+ }
+
+ return (long)statistics.mean();
+ }
+
+ @Override
+ public void updateAttempt(TaskAttemptStatus status, long timestamp) {
+ String stateString = status.stateString.toString();
+
+ TaskAttemptID attemptID = status.id;
+ TaskID taskID = attemptID.taskID;
+ JobID jobID = taskID.jobID;
+ Job job = context.getJob(jobID);
+
+ if (job == null) {
+ return;
+ }
+
+ Task task = job.getTask(taskID);
+
+ if (task == null) {
+ return;
+ }
+
+ Long boxedStart = startTimes.get(attemptID);
+ long start = boxedStart == null ? Long.MIN_VALUE : boxedStart;
+
+ if (stateString.equals(TaskAttemptState.SUCCEEDED.name())) {
+ boolean isNew = false;
+ // is this a new success?
+ synchronized (doneTasks) {
+ if (!doneTasks.contains(task)) {
+ doneTasks.add(task);
+ isNew = true;
+ }
+ }
+
+ // It's a new completion
+ // Note that if a task completes twice [because of a previous speculation
+ // and a race, or a success followed by loss of the machine with the
+ // local data] we only count the first one.
+ if (isNew) {
+ long finish = timestamp;
+ if (start > 1L && finish > 1L && start <= finish) {
+ long duration = finish - start;
+
+ DataStatistics statistics
+ = dataStatisticsForTask(taskID);
+
+ if (statistics != null) {
+ statistics.add(duration);
+ }
+ }
+ }
+ }
+ }
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/speculate/TaskRuntimeEstimator.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/speculate/TaskRuntimeEstimator.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/speculate/TaskRuntimeEstimator.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/speculate/TaskRuntimeEstimator.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,90 @@
+/**
+* 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.mapreduce.v2.app.speculate;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.mapreduce.v2.app.AppContext;
+import org.apache.hadoop.mapreduce.v2.app.job.event.TaskAttemptStatusUpdateEvent.TaskAttemptStatus;
+
+import org.apache.hadoop.mapreduce.v2.api.TaskID;
+import org.apache.hadoop.mapreduce.v2.api.TaskAttemptID;
+
+
+public interface TaskRuntimeEstimator {
+ public void enrollAttempt(TaskAttemptStatus reportedStatus, long timestamp);
+
+ public long attemptEnrolledTime(TaskAttemptID attemptID);
+
+ public void updateAttempt(TaskAttemptStatus reportedStatus, long timestamp);
+
+ public void contextualize(Configuration conf, AppContext context);
+
+ /**
+ *
+ * Find a maximum reasonable execution wallclock time. Includes the time
+ * already elapsed.
+ *
+ * Find a maximum reasonable execution time. Includes the time
+ * already elapsed. If the projected total execution time for this task
+ * ever exceeds its reasonable execution time, we may speculate it.
+ *
+ * @param id the {@link TaskID} of the task we are asking about
+ * @return the task's maximum reasonable runtime, or MAX_VALUE if
+ * we don't have enough information to rule out any runtime,
+ * however long.
+ *
+ */
+ public long thresholdRuntime(TaskID id);
+
+ /**
+ *
+ * Estimate a task attempt's total runtime. Includes the time already
+ * elapsed.
+ *
+ * @param id the {@link TaskAttemptID} of the attempt we are asking about
+ * @return our best estimate of the attempt's runtime, or {@code -1} if
+ * we don't have enough information yet to produce an estimate.
+ *
+ */
+ public long estimatedRuntime(TaskAttemptID id);
+
+ /**
+ *
+ * Estimates how long a new attempt on this task will take if we start
+ * one now
+ *
+ * @param id the {@link TaskID} of the task we are asking about
+ * @return our best estimate of a new attempt's runtime, or {@code -1} if
+ * we don't have enough information yet to produce an estimate.
+ *
+ */
+ public long estimatedNewAttemptRuntime(TaskID id);
+
+ /**
+ *
+ * Computes the width of the error band of our estimate of the task
+ * runtime as returned by {@link estimatedRuntime}
+ *
+ * @param id the {@link TaskAttemptID} of the attempt we are asking about
+ * @return our best estimate of the attempt's runtime, or {@code -1} if
+ * we don't have enough information yet to produce an estimate.
+ *
+ */
+ public long runtimeEstimateVariance(TaskAttemptID id);
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/speculate/TaskSpeculationPredicate.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/speculate/TaskSpeculationPredicate.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/speculate/TaskSpeculationPredicate.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/speculate/TaskSpeculationPredicate.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,38 @@
+/**
+* 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.mapreduce.v2.app.speculate;
+
+import org.apache.hadoop.mapreduce.v2.app.AppContext;
+import org.apache.hadoop.mapreduce.v2.app.job.Job;
+import org.apache.hadoop.mapreduce.v2.app.job.Task;
+import org.apache.hadoop.mapreduce.v2.api.JobID;
+import org.apache.hadoop.mapreduce.v2.api.TaskID;
+
+public class TaskSpeculationPredicate {
+ boolean canSpeculate(AppContext context, TaskID taskID) {
+ // This class rejects speculating any task that already has speculations,
+ // or isn't running.
+ // Subclasses should call TaskSpeculationPredicate.canSpeculate(...) , but
+ // can be even more restrictive.
+ JobID jobID = taskID.jobID;
+ Job job = context.getJob(jobID);
+ Task task = job.getTask(taskID);
+ return task.getAttempts().size() == 1;
+ }
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/taskclean/TaskCleaner.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/taskclean/TaskCleaner.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/taskclean/TaskCleaner.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/taskclean/TaskCleaner.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,28 @@
+/**
+* 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.mapreduce.v2.app.taskclean;
+
+import org.apache.hadoop.yarn.event.EventHandler;
+
+public interface TaskCleaner extends EventHandler<TaskCleanupEvent> {
+
+ enum EventType {
+ TASK_CLEAN
+ }
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/taskclean/TaskCleanerImpl.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/taskclean/TaskCleanerImpl.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/taskclean/TaskCleanerImpl.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/taskclean/TaskCleanerImpl.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,108 @@
+/**
+* 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.mapreduce.v2.app.taskclean;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.mapreduce.v2.app.AppContext;
+import org.apache.hadoop.mapreduce.v2.app.job.event.TaskAttemptEvent;
+import org.apache.hadoop.mapreduce.v2.app.job.event.TaskAttemptEventType;
+import org.apache.hadoop.yarn.YarnException;
+import org.apache.hadoop.yarn.service.AbstractService;
+
+public class TaskCleanerImpl extends AbstractService implements TaskCleaner {
+
+ private static final Log LOG = LogFactory.getLog(TaskCleanerImpl.class);
+
+ private final AppContext context;
+ private ThreadPoolExecutor launcherPool;
+ private Thread eventHandlingThread;
+ private BlockingQueue<TaskCleanupEvent> eventQueue =
+ new LinkedBlockingQueue<TaskCleanupEvent>();
+
+ public TaskCleanerImpl(AppContext context) {
+ super("TaskCleaner");
+ this.context = context;
+ }
+
+ public void start() {
+ launcherPool = new ThreadPoolExecutor(1, 5, 1,
+ TimeUnit.HOURS, new LinkedBlockingQueue<Runnable>());
+ eventHandlingThread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ TaskCleanupEvent event = null;
+ while (!Thread.currentThread().isInterrupted()) {
+ try {
+ event = eventQueue.take();
+ } catch (InterruptedException e) {
+ LOG.error("Returning, interrupted : " + e);
+ return;
+ }
+ // the events from the queue are handled in parallel
+ // using a thread pool
+ launcherPool.execute(new EventProcessor(event)); }
+ }
+ });
+ eventHandlingThread.start();
+ super.start();
+ }
+
+ public void stop() {
+ eventHandlingThread.interrupt();
+ launcherPool.shutdown();
+ super.stop();
+ }
+
+ private class EventProcessor implements Runnable {
+ private TaskCleanupEvent event;
+
+ EventProcessor(TaskCleanupEvent event) {
+ this.event = event;
+ }
+
+ @Override
+ public void run() {
+ LOG.info("Processing the event " + event.toString());
+ try {
+ event.getCommitter().abortTask(event.getAttemptContext());
+ } catch (Exception e) {
+ LOG.warn("Task cleanup failed for attempt " + event.getAttemptID(), e);
+ }
+ context.getEventHandler().handle(
+ new TaskAttemptEvent(event.getAttemptID(),
+ TaskAttemptEventType.TA_CLEANUP_DONE));
+ }
+ }
+
+ @Override
+ public void handle(TaskCleanupEvent event) {
+ try {
+ eventQueue.put(event);
+ } catch (InterruptedException e) {
+ throw new YarnException(e);
+ }
+ }
+
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/taskclean/TaskCleanupEvent.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/taskclean/TaskCleanupEvent.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/taskclean/TaskCleanupEvent.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/taskclean/TaskCleanupEvent.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,56 @@
+/**
+* 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.mapreduce.v2.app.taskclean;
+
+import org.apache.hadoop.mapreduce.OutputCommitter;
+import org.apache.hadoop.mapreduce.TaskAttemptContext;
+import org.apache.hadoop.yarn.event.AbstractEvent;
+import org.apache.hadoop.mapreduce.v2.api.TaskAttemptID;
+
+/**
+ * This class encapsulates task cleanup event.
+ *
+ */
+public class TaskCleanupEvent extends AbstractEvent<TaskCleaner.EventType> {
+
+ private final TaskAttemptID attemptID;
+ private final OutputCommitter committer;
+ private final TaskAttemptContext attemptContext;
+
+ public TaskCleanupEvent(TaskAttemptID attemptID, OutputCommitter committer,
+ TaskAttemptContext attemptContext) {
+ super(TaskCleaner.EventType.TASK_CLEAN);
+ this.attemptID = attemptID;
+ this.committer = committer;
+ this.attemptContext = attemptContext;
+ }
+
+ public TaskAttemptID getAttemptID() {
+ return attemptID;
+ }
+
+ public OutputCommitter getCommitter() {
+ return committer;
+ }
+
+ public TaskAttemptContext getAttemptContext() {
+ return attemptContext;
+ }
+
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AMParams.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AMParams.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AMParams.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AMParams.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,30 @@
+/**
+* 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.mapreduce.v2.app.webapp;
+
+/**
+ * Params constants for the AM webapp
+ */
+interface AMParams {
+ static final String RM_WEB = "rm.web";
+ static final String APP_ID = "app.id";
+ static final String JOB_ID = "job.id";
+ static final String TASK_ID = "task.id";
+ static final String TASK_TYPE = "task.type";
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AMWebApp.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AMWebApp.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AMWebApp.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AMWebApp.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,39 @@
+/**
+* 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.mapreduce.v2.app.webapp;
+
+import static org.apache.hadoop.yarn.util.StringHelper.*;
+
+import org.apache.hadoop.yarn.webapp.WebApp;
+
+/**
+ * Application master webapp
+ */
+public class AMWebApp extends WebApp implements AMParams {
+
+ @Override
+ public void setup() {
+ route("/", AppController.class);
+ route("/app", AppController.class);
+ route(pajoin("/job", JOB_ID), AppController.class, "job");
+ route(pajoin("/jobcounters", JOB_ID), AppController.class, "jobCounters");
+ route(pajoin("/tasks", JOB_ID, TASK_TYPE), AppController.class, "tasks");
+ route(pajoin("/task", TASK_ID), AppController.class, "task");
+ }
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/App.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/App.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/App.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/App.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,38 @@
+/**
+* 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.mapreduce.v2.app.webapp;
+
+import com.google.inject.Inject;
+import com.google.inject.servlet.RequestScoped;
+
+import org.apache.hadoop.mapreduce.v2.app.AppContext;
+import org.apache.hadoop.mapreduce.v2.app.job.Job;
+import org.apache.hadoop.mapreduce.v2.app.job.Task;
+
+@RequestScoped
+class App {
+ final AppContext context;
+ Job job;
+ Task task;
+
+ @Inject
+ App(AppContext ctx) {
+ context = ctx;
+ }
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AppController.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AppController.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AppController.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AppController.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,141 @@
+/**
+* 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.mapreduce.v2.app.webapp;
+
+import java.util.Locale;
+import org.apache.commons.lang.StringUtils;
+import com.google.inject.Inject;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.mapreduce.v2.util.MRApps;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.util.Apps;
+import org.apache.hadoop.yarn.webapp.Controller;
+import org.apache.hadoop.mapreduce.v2.api.JobID;
+import org.apache.hadoop.mapreduce.v2.api.TaskID;
+
+import static org.apache.hadoop.mapreduce.v2.app.webapp.AMWebApp.*;
+import static org.apache.hadoop.yarn.util.StringHelper.*;
+
+public class AppController extends Controller implements AMParams {
+ final App app;
+
+ @Inject AppController(App app, Configuration conf, RequestContext ctx) {
+ super(ctx);
+ this.app = app;
+ set(APP_ID, Apps.toString(app.context.getApplicationID()));
+ set(RM_WEB, join("http://",
+ conf.get(YarnConfiguration.RM_WEBAPP_BIND_ADDRESS, "localhost:8888")));
+ }
+
+ @Override public void index() {
+ setTitle(join("MapReduce Application ", $(APP_ID)));
+ }
+
+ public void info() {
+ info("Application Master Overview").
+ _("Application ID:", $(APP_ID)).
+ _("Application Name:", "FIXAPI: app name").
+ _("User:", app.context.getUser()).
+ _("Started on:", "FIXAPI: started on").
+ _("Elasped: ", "FIXAPI: elapsed time");
+ render(InfoPage.class);
+ }
+
+ public void job() {
+ requireJob();
+ render(JobPage.class);
+ }
+
+ public void jobCounters() {
+ requireJob();
+ if (app.job != null) {
+ setTitle(join("Counters for ", $(JOB_ID)));
+ }
+ render(CountersPage.class);
+ }
+
+ public void tasks() {
+ requireJob();
+ if (app.job != null) {
+ try {
+ String tt = $(TASK_TYPE);
+ tt = tt.isEmpty() ? "All" : StringUtils.capitalize(MRApps.taskType(tt).
+ toString().toLowerCase(Locale.US));
+ setTitle(join(tt, " Tasks for ", $(JOB_ID)));
+ } catch (Exception e) {
+ badRequest(e.getMessage());
+ }
+ }
+ render(TasksPage.class);
+ }
+
+ public void task() {
+ requireTask();
+ if (app.task != null) {
+ setTitle(join("Attempts for ", $(TASK_ID)));
+ }
+ render(TaskPage.class);
+ }
+
+ void badRequest(String s) {
+ setStatus(response().SC_BAD_REQUEST);
+ setTitle(join("Bad request: ", s));
+ }
+
+ void notFound(String s) {
+ setStatus(response().SC_NOT_FOUND);
+ setTitle(join("Not found: ", s));
+ }
+
+ void requireJob() {
+ try {
+ if ($(JOB_ID).isEmpty()) {
+ throw new RuntimeException("missing job ID");
+ }
+ JobID jobID = MRApps.toJobID($(JOB_ID));
+ app.job = app.context.getJob(jobID);
+ if (app.job == null) {
+ notFound($(JOB_ID));
+ }
+ } catch (Exception e) {
+ badRequest(e.getMessage());
+ }
+ }
+
+ void requireTask() {
+ try {
+ if ($(TASK_ID).isEmpty()) {
+ throw new RuntimeException("missing task ID");
+ }
+ TaskID taskID = MRApps.toTaskID($(TASK_ID));
+ app.job = app.context.getJob(taskID.jobID);
+ if (app.job == null) {
+ notFound(MRApps.toString(taskID.jobID));
+ } else {
+ app.task = app.job.getTask(taskID);
+ if (app.task == null) {
+ notFound($(TASK_ID));
+ }
+ }
+ } catch (Exception e) {
+ badRequest(e.getMessage());
+ }
+ }
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AppView.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AppView.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AppView.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/AppView.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,59 @@
+/**
+* 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.mapreduce.v2.app.webapp;
+
+import org.apache.hadoop.yarn.webapp.SubView;
+import org.apache.hadoop.yarn.webapp.view.TwoColumnLayout;
+
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.*;
+
+public class AppView extends TwoColumnLayout {
+
+ @Override protected void preHead(Page.HTML<_> html) {
+ commonPreHead(html);
+ set(DATATABLES_ID, "jobs");
+ set(initID(DATATABLES, "jobs"), jobsTableInit());
+ setTableStyles(html, "jobs");
+ }
+
+ protected void commonPreHead(Page.HTML<_> html) {
+ html.meta_http("refresh", "10");
+ set(ACCORDION_ID, "nav");
+ set(initID(ACCORDION, "nav"), "{autoHeight:false, active:1}");
+ set(THEMESWITCHER_ID, "themeswitcher");
+ }
+
+ @Override
+ protected Class<? extends SubView> nav() {
+ return NavBlock.class;
+ }
+
+ @Override
+ protected Class<? extends SubView> content() {
+ return JobsBlock.class;
+ }
+
+ private String jobsTableInit() {
+ return tableInit().
+ append(",aoColumns:[{sType:'title-numeric'},").
+ append("null,null,{sType:'title-numeric', bSearchable:false},null,").
+ append("null,{sType:'title-numeric',bSearchable:false}, null, null]}").
+ toString();
+ }
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/CountersBlock.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/CountersBlock.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/CountersBlock.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/CountersBlock.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,161 @@
+/**
+* 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.mapreduce.v2.app.webapp;
+
+import com.google.inject.Inject;
+import java.util.Map;
+
+import org.apache.hadoop.mapreduce.v2.app.AppContext;
+import org.apache.hadoop.mapreduce.v2.app.job.Job;
+import org.apache.hadoop.mapreduce.v2.app.job.Task;
+import org.apache.hadoop.mapreduce.v2.app.job.impl.JobImpl;
+import org.apache.hadoop.mapreduce.v2.util.MRApps;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.*;
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+import org.apache.hadoop.mapreduce.v2.api.Counter;
+import org.apache.hadoop.mapreduce.v2.api.CounterGroup;
+import org.apache.hadoop.mapreduce.v2.api.Counters;
+import org.apache.hadoop.mapreduce.v2.api.JobID;
+import org.apache.hadoop.mapreduce.v2.api.TaskID;
+
+import static org.apache.hadoop.mapreduce.v2.app.webapp.AMWebApp.*;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.*;
+
+public class CountersBlock extends HtmlBlock {
+ Job job;
+ Task task;
+ Counters total;
+ Counters map;
+ Counters reduce;
+
+ @Inject CountersBlock(AppContext appCtx, ViewContext ctx) {
+ super(ctx);
+ getCounters(appCtx);
+ }
+
+ @Override protected void render(Block html) {
+ if (job == null) {
+ html.
+ p()._("Sorry, no counters for nonexistent", $(JOB_ID, "job"))._();
+ return;
+ }
+ if (!$(TASK_ID).isEmpty() && task == null) {
+ html.
+ p()._("Sorry, no counters for nonexistent", $(TASK_ID, "task"))._();
+ return;
+ }
+ int numGroups = 0;
+ TBODY<TABLE<DIV<Hamlet>>> tbody = html.
+ div(_INFO_WRAP).
+ table("#counters").
+ thead().
+ tr().
+ th(".group.ui-state-default", "Counter Group").
+ th(".ui-state-default", "Counters")._()._().
+ tbody();
+ for (CounterGroup g : total.groups.values()) {
+ CounterGroup mg = map == null ? null : map.groups.get(g.name);
+ CounterGroup rg = reduce == null ? null : reduce.groups.get(g.name);
+ ++numGroups;
+ // This is mostly for demonstration :) Typically we'd introduced
+ // a CounterGroup block to reduce the verbosity. OTOH, this
+ // serves as an indicator of where we're in the tag hierarchy.
+ TR<THEAD<TABLE<TD<TR<TBODY<TABLE<DIV<Hamlet>>>>>>>> groupHeadRow = tbody.
+ tr().
+ th().$title(g.name.toString()).
+ _(fixGroupDisplayName(g.displayname))._().
+ td().$class(C_TABLE).
+ table(".dt-counters").
+ thead().
+ tr().th(".name", "Name");
+ if (map != null) {
+ groupHeadRow.th("Map").th("Reduce");
+ }
+ // Ditto
+ TBODY<TABLE<TD<TR<TBODY<TABLE<DIV<Hamlet>>>>>>> group = groupHeadRow.
+ th(map == null ? "Value" : "Total")._()._().
+ tbody();
+ for (Counter counter : g.counters.values()) {
+ // Ditto
+ TR<TBODY<TABLE<TD<TR<TBODY<TABLE<DIV<Hamlet>>>>>>>> groupRow = group.
+ tr().
+ td().$title(counter.name.toString()).
+ _(counter.displayName.toString())._();
+ if (map != null) {
+ Counter mc = mg == null ? null : mg.counters.get(counter.name);
+ Counter rc = rg == null ? null : rg.counters.get(counter.name);
+ groupRow.
+ td(mc == null ? "0" : String.valueOf(mc.value)).
+ td(rc == null ? "0" : String.valueOf(rc.value));
+ }
+ groupRow.td(String.valueOf(counter.value))._();
+ }
+ group._()._()._()._();
+ }
+ tbody._()._()._();
+ }
+
+ private void getCounters(AppContext ctx) {
+ JobID jobID = null;
+ TaskID taskID = null;
+ String tid = $(TASK_ID);
+ if (!tid.isEmpty()) {
+ taskID = MRApps.toTaskID(tid);
+ jobID = taskID.jobID;
+ } else {
+ String jid = $(JOB_ID);
+ if (!jid.isEmpty()) {
+ jobID = MRApps.toJobID(jid);
+ }
+ }
+ if (jobID == null) {
+ return;
+ }
+ job = ctx.getJob(jobID);
+ if (job == null) {
+ return;
+ }
+ if (taskID != null) {
+ task = job.getTask(taskID);
+ if (task == null) {
+ return;
+ }
+ total = task.getCounters();
+ return;
+ }
+ // Get all types of counters
+ Map<TaskID, Task> tasks = job.getTasks();
+ total = JobImpl.newCounters();
+ map = JobImpl.newCounters();
+ reduce = JobImpl.newCounters();
+ for (Task t : tasks.values()) {
+ Counters counters = t.getCounters();
+ JobImpl.incrAllCounters(total, counters);
+ switch (t.getType()) {
+ case MAP: JobImpl.incrAllCounters(map, counters); break;
+ case REDUCE: JobImpl.incrAllCounters(reduce, counters); break;
+ }
+ }
+ }
+
+ private String fixGroupDisplayName(CharSequence name) {
+ return name.toString().replace(".", ".\u200B").replace("$", "\u200B$");
+ }
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/CountersPage.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/CountersPage.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/CountersPage.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/CountersPage.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,47 @@
+/**
+* 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.mapreduce.v2.app.webapp;
+
+import org.apache.hadoop.yarn.webapp.SubView;
+
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.*;
+
+public class CountersPage extends AppView {
+
+ @Override protected void preHead(Page.HTML<_> html) {
+ commonPreHead(html);
+ set(initID(ACCORDION, "nav"), "{autoHeight:false, active:2}");
+ set(DATATABLES_SELECTOR, "#counters .dt-counters");
+ set(initSelector(DATATABLES),
+ "{bJQueryUI:true, sDom:'t', iDisplayLength:-1}");
+ }
+
+ @Override protected void postHead(Page.HTML<_> html) {
+ html.
+ style("#counters, .dt-counters { table-layout: fixed }",
+ "#counters th { overflow: hidden; vertical-align: center }",
+ "#counters .dataTables_wrapper { min-height: 1em }",
+ "#counters .group { width: 10em }",
+ "#counters .name { width: 30em }");
+ }
+
+ @Override protected Class<? extends SubView> content() {
+ return CountersBlock.class;
+ }
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/InfoPage.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/InfoPage.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/InfoPage.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/InfoPage.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,34 @@
+/**
+* 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.mapreduce.v2.app.webapp;
+
+import org.apache.hadoop.yarn.webapp.SubView;
+import org.apache.hadoop.yarn.webapp.view.InfoBlock;
+
+public class InfoPage extends AppView {
+
+ @Override protected void preHead(Page.HTML<_> html) {
+ commonPreHead(html);
+ setTitle("About the Application Master");
+ }
+
+ @Override protected Class<? extends SubView> content() {
+ return InfoBlock.class;
+ }
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/JobBlock.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/JobBlock.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/JobBlock.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/JobBlock.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,130 @@
+/**
+* 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.mapreduce.v2.app.webapp;
+
+import com.google.inject.Inject;
+import java.util.Date;
+import java.util.Map;
+
+import org.apache.hadoop.mapreduce.v2.api.JobID;
+import org.apache.hadoop.mapreduce.v2.api.JobReport;
+import org.apache.hadoop.mapreduce.v2.api.TaskID;
+import org.apache.hadoop.mapreduce.v2.app.AppContext;
+import org.apache.hadoop.mapreduce.v2.app.job.Job;
+import org.apache.hadoop.mapreduce.v2.app.job.Task;
+import org.apache.hadoop.mapreduce.v2.util.MRApps;
+import org.apache.hadoop.util.StringUtils;
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+import org.apache.hadoop.yarn.webapp.view.InfoBlock;
+import static org.apache.hadoop.mapreduce.v2.app.webapp.AMWebApp.*;
+import static org.apache.hadoop.yarn.util.StringHelper.*;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.*;
+
+public class JobBlock extends HtmlBlock {
+ final AppContext appContext;
+ int runningMaps = 0;
+ int pendingMaps = 0;
+ int runningReds = 0;
+ int pendingReds = 0;
+
+ @Inject JobBlock(AppContext appctx) {
+ appContext = appctx;
+ }
+
+ @Override protected void render(Block html) {
+ String jid = $(JOB_ID);
+ if (jid.isEmpty()) {
+ html.
+ p()._("Sorry, can't do anything without a JobID.")._();
+ return;
+ }
+ JobID jobID = MRApps.toJobID(jid);
+ Job job = appContext.getJob(jobID);
+ if (job == null) {
+ html.
+ p()._("Sorry, ", jid, " not found.")._();
+ return;
+ }
+ JobReport jobReport = job.getReport();
+ String mapPct = percent(jobReport.mapProgress);
+ String reducePct = percent(jobReport.reduceProgress);
+ int maps = job.getTotalMaps();
+ int mapsComplete = job.getCompletedMaps();
+ int reduces = job.getTotalReduces();
+ int reducesComplete = job.getCompletedReduces();
+ countTasks(job);
+ info("Job Overview").
+ _("Job Name:", job.getName()).
+ _("State:", job.getState()).
+ _("Started:", new Date(jobReport.startTime)).
+ _("Elapsed:", StringUtils.formatTime(System.currentTimeMillis()
+ - jobReport.startTime));
+ html.
+ _(InfoBlock.class).
+ div(_INFO_WRAP).
+ table("#job").
+ tr().
+ th(_TH, "Task Type").
+ th(_TH, "Progress").
+ th(_TH, "Total").
+ th(_TH, "Pending").
+ th(_TH, "Running").
+ th(_TH, "Complete")._().
+ tr(_ODD).
+ th().
+ a(url("tasks", jid, "m"), "Map")._().
+ td().
+ div(_PROGRESSBAR).
+ $title(join(mapPct, '%')). // tooltip
+ div(_PROGRESSBAR_VALUE).
+ $style(join("width:", mapPct, '%'))._()._()._().
+ td(String.valueOf(maps)).
+ td(String.valueOf(pendingMaps)).
+ td(String.valueOf(runningMaps)).
+ td(String.valueOf(mapsComplete))._().
+ tr(_EVEN).
+ th().
+ a(url("tasks", jid, "r"), "Reduce")._().
+ td().
+ div(_PROGRESSBAR).
+ $title(join(reducePct, '%')). // tooltip
+ div(_PROGRESSBAR_VALUE).
+ $style(join("width:", reducePct, '%'))._()._()._().
+ td(String.valueOf(reduces)).
+ td(String.valueOf(pendingReds)).
+ td(String.valueOf(runningReds)).
+ td(String.valueOf(reducesComplete))._()._()._();
+ }
+
+ private void countTasks(Job job) {
+ Map<TaskID, Task> tasks = job.getTasks();
+ for (Task task : tasks.values()) {
+ switch (task.getType()) {
+ case MAP: switch (task.getState()) {
+ case RUNNING: ++runningMaps; break;
+ case SCHEDULED: ++pendingMaps; break;
+ } break;
+ case REDUCE: switch(task.getState()) {
+ case RUNNING: ++runningReds; break;
+ case SCHEDULED: ++pendingReds; break;
+ } break;
+ }
+ }
+ }
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/JobPage.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/JobPage.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/JobPage.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/JobPage.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,42 @@
+/**
+* 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.mapreduce.v2.app.webapp;
+
+import static org.apache.hadoop.mapreduce.v2.app.webapp.AMWebApp.*;
+import static org.apache.hadoop.yarn.util.StringHelper.*;
+import static org.apache.hadoop.yarn.webapp.Params.*;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.*;
+
+import org.apache.hadoop.yarn.webapp.SubView;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.*;
+
+public class JobPage extends AppView {
+
+ @Override protected void preHead(Page.HTML<_> html) {
+ String jobID = $(JOB_ID);
+ set(TITLE, jobID.isEmpty() ? "Bad request: missing job ID"
+ : join("MapReduce Job ", $(JOB_ID)));
+ commonPreHead(html);
+ set(initID(ACCORDION, "nav"), "{autoHeight:false, active:2}");
+ }
+
+ @Override protected Class<? extends SubView> content() {
+ return JobBlock.class;
+ }
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/JobsBlock.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/JobsBlock.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/JobsBlock.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/JobsBlock.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,92 @@
+/**
+* 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.mapreduce.v2.app.webapp;
+
+import com.google.inject.Inject;
+
+import org.apache.hadoop.mapreduce.v2.app.AppContext;
+import org.apache.hadoop.mapreduce.v2.app.job.Job;
+import org.apache.hadoop.mapreduce.v2.util.MRApps;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.*;
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+import org.apache.hadoop.mapreduce.v2.api.JobReport;
+
+import static org.apache.hadoop.yarn.util.StringHelper.*;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.*;
+
+public class JobsBlock extends HtmlBlock {
+ final AppContext appContext;
+
+ @Inject JobsBlock(AppContext appCtx) {
+ appContext = appCtx;
+ }
+
+ @Override protected void render(Block html) {
+ TBODY<TABLE<Hamlet>> tbody = html.
+ h2("Active Jobs").
+ table("#jobs").
+ thead().
+ tr().
+ th(".id", "Job ID").
+ th(".name", "Name").
+ th(".state", "State").
+ th("Map Progress").
+ th("Maps Total").
+ th("Maps Completed").
+ th("Reduce Progress").
+ th("Reduces Total").
+ th("Reduces Completed")._()._().
+ tbody();
+ for (Job job : appContext.getAllJobs().values()) {
+ String jobID = MRApps.toString(job.getID());
+ JobReport report = job.getReport();
+ String mapPct = percent(report.mapProgress);
+ String mapsTotal = String.valueOf(job.getTotalMaps());
+ String mapsCompleted = String.valueOf(job.getCompletedMaps());
+ String reducePct = percent(report.reduceProgress);
+ String reduceTotal = String.valueOf(job.getTotalReduces());
+ String reduceCompleted = String.valueOf(job.getCompletedReduces());
+ tbody.
+ tr().
+ td().
+ span().$title(String.valueOf(job.getID().id))._(). // for sorting
+ a(url("job", jobID), jobID)._().
+ td(job.getName().toString()).
+ td(job.getState().toString()).
+ td().
+ span().$title(mapPct)._(). // for sorting
+ div(_PROGRESSBAR).
+ $title(join(mapPct, '%')). // tooltip
+ div(_PROGRESSBAR_VALUE).
+ $style(join("width:", mapPct, '%'))._()._()._().
+ td(mapsTotal).
+ td(mapsCompleted).
+ td().
+ span().$title(reducePct)._(). // for sorting
+ div(_PROGRESSBAR).
+ $title(join(reducePct, '%')). // tooltip
+ div(_PROGRESSBAR_VALUE).
+ $style(join("width:", reducePct, '%'))._()._()._().
+ td(reduceTotal).
+ td(reduceCompleted)._();
+ }
+ tbody._()._();
+ }
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/NavBlock.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/NavBlock.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/NavBlock.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/NavBlock.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,67 @@
+/**
+* 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.mapreduce.v2.app.webapp;
+
+import com.google.inject.Inject;
+
+import static org.apache.hadoop.mapreduce.v2.app.webapp.AMWebApp.*;
+
+import org.apache.hadoop.mapreduce.v2.util.MRApps;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.*;
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+
+public class NavBlock extends HtmlBlock {
+ final App app;
+
+ @Inject NavBlock(App app) { this.app = app; }
+
+ @Override protected void render(Block html) {
+ String rmweb = $(RM_WEB);
+ DIV<Hamlet> nav = html.
+ div("#nav").
+ h3("Cluster").
+ ul().
+ li().a(url(rmweb, prefix(), "cluster"), "About")._().
+ li().a(url(rmweb, prefix(), "apps"), "Applications")._().
+ li().a(url(rmweb, prefix(), "scheduler"), "Scheduler")._()._().
+ h3("Application").
+ ul().
+ li().a(url("app/info"), "About")._().
+ li().a(url("app"), "Jobs")._()._();
+ if (app.job != null) {
+ String jobid = MRApps.toString(app.job.getID());
+ nav.
+ h3("Job").
+ ul().
+ li().a(url("job", jobid), "Overview")._().
+ li().a(url("jobcounters", jobid), "Counters")._().
+ li().a(url("tasks", jobid, "m"), "Map tasks")._().
+ li().a(url("tasks", jobid, "r"), "Reduce tasks")._()._();
+ }
+ nav.
+ h3("Tools").
+ ul().
+ li().a("/conf", "Configuration")._().
+ li().a("/logs", "Local logs")._().
+ li().a("/stacks", "Server stacks")._().
+ li().a("/metrics", "Server metrics")._()._()._().
+ div("#themeswitcher")._();
+ }
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/TaskPage.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/TaskPage.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/TaskPage.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/TaskPage.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,101 @@
+/**
+* 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.mapreduce.v2.app.webapp;
+
+import com.google.common.base.Joiner;
+import com.google.inject.Inject;
+
+import org.apache.hadoop.mapreduce.v2.app.job.TaskAttempt;
+import org.apache.hadoop.mapreduce.v2.util.MRApps;
+import org.apache.hadoop.yarn.webapp.SubView;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.*;
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+import org.apache.hadoop.mapreduce.v2.api.TaskAttemptReport;
+
+import static org.apache.hadoop.yarn.util.StringHelper.*;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.*;
+
+class TaskPage extends AppView {
+
+ static class AttemptsBlock extends HtmlBlock {
+ final App app;
+
+ @Inject
+ AttemptsBlock(App ctx) {
+ app = ctx;
+ }
+
+ @Override
+ protected void render(Block html) {
+ if (app.task == null) {
+ html.
+ h2($(TITLE));
+ return;
+ }
+ TBODY<TABLE<Hamlet>> tbody = html.
+ table("#attempts").
+ thead().
+ tr().
+ th(".id", "Attempt").
+ th(".progress", "Progress").
+ th(".state", "State").
+ th(".node", "Node").
+ th(".tsh", "Started").
+ th(".tsh", "Finished").
+ th(".tsh", "Elapsed").
+ th(".note", "Note")._()._().
+ tbody();
+ for (TaskAttempt ta : app.task.getAttempts().values()) {
+ String taid = MRApps.toString(ta.getID());
+ String progress = percent(ta.getProgress());
+ String node = ta.getAssignedContainerMgrAddress();
+ TaskAttemptReport report = ta.getReport();
+ long elapsed = Times.elapsed(report.startTime, report.finishTime);
+ tbody.
+ tr().
+ td(".id", taid).
+ td(".progress", progress).
+ td(".state", ta.getState().toString()).
+ td(".node", node).
+ td(".ts", String.valueOf(report.startTime)).
+ td(".ts", String.valueOf(report.finishTime)).
+ td(".dt", String.valueOf(elapsed)).
+ td(".note", Joiner.on('\n').join(ta.getDiagnostics()))._();
+ }
+ tbody._()._();
+ }
+ }
+
+ @Override protected void preHead(Page.HTML<_> html) {
+ commonPreHead(html);
+ set(initID(ACCORDION, "nav"), "{autoHeight:false, active:2}");
+ set(DATATABLES_ID, "attempts");
+ set(initID(DATATABLES, "attempts"), attemptsTableInit());
+ setTableStyles(html, "attempts");
+ }
+
+ @Override protected Class<? extends SubView> content() {
+ return AttemptsBlock.class;
+ }
+
+ private String attemptsTableInit() {
+ return tableInit().append("}").toString();
+ }
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/TasksBlock.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/TasksBlock.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/TasksBlock.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/TasksBlock.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,102 @@
+/**
+* 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.mapreduce.v2.app.webapp;
+
+import com.google.inject.Inject;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.hadoop.mapreduce.v2.app.job.Task;
+import org.apache.hadoop.mapreduce.v2.util.MRApps;
+import org.apache.hadoop.util.StringUtils;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
+import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.*;
+import org.apache.hadoop.yarn.webapp.view.HtmlBlock;
+
+import org.apache.hadoop.mapreduce.v2.api.TaskReport;
+import org.apache.hadoop.mapreduce.v2.api.TaskType;
+
+import static org.apache.hadoop.mapreduce.v2.app.webapp.AMWebApp.*;
+import static org.apache.hadoop.yarn.util.StringHelper.*;
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.*;
+
+public class TasksBlock extends HtmlBlock {
+ final App app;
+ final SimpleDateFormat dateFormat =
+ new SimpleDateFormat("d-MMM-yyyy HH:mm:ss");
+
+ @Inject TasksBlock(App app) {
+ this.app = app;
+ }
+
+ @Override protected void render(Block html) {
+ if (app.job == null) {
+ html.
+ h2($(TITLE));
+ return;
+ }
+ TaskType type = null;
+ String symbol = $(TASK_TYPE);
+ if (!symbol.isEmpty()) {
+ type = MRApps.taskType(symbol);
+ }
+ TBODY<TABLE<Hamlet>> tbody = html.
+ table("#tasks").
+ thead().
+ tr().
+ th("Task").
+ th("Progress").
+ th("State").
+ th("Start Time").
+ th("Finish Time").
+ th("Elapsed Time")._()._().
+ tbody();
+ for (Task task : app.job.getTasks().values()) {
+ if (type != null && task.getType() != type) {
+ continue;
+ }
+ String tid = MRApps.toString(task.getID());
+ TaskReport report = task.getReport();
+ String pct = percent(report.progress);
+ long elapsed = Times.elapsed(report.startTime, report.finishTime);
+ tbody.
+ tr().
+ td().
+ br().$title(String.valueOf(task.getID().id))._(). // sorting
+ a(url("task", tid), tid)._().
+ td().
+ br().$title(pct)._().
+ div(_PROGRESSBAR).
+ $title(join(pct, '%')). // tooltip
+ div(_PROGRESSBAR_VALUE).
+ $style(join("width:", pct, '%'))._()._()._().
+ td(report.state.toString()).
+ td().
+ br().$title(String.valueOf(report.startTime))._().
+ _(dateFormat.format(new Date(report.startTime)))._().
+ td().
+ br().$title(String.valueOf(report.finishTime))._().
+ _(dateFormat.format(new Date(report.finishTime)))._().
+ td().
+ br().$title(String.valueOf(elapsed))._().
+ _(StringUtils.formatTime(elapsed))._()._();
+ }
+ tbody._()._();
+ }
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/TasksPage.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/TasksPage.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/TasksPage.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/TasksPage.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,45 @@
+/**
+* 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.mapreduce.v2.app.webapp;
+
+import org.apache.hadoop.yarn.webapp.SubView;
+
+import static org.apache.hadoop.yarn.webapp.view.JQueryUI.*;
+
+public class TasksPage extends AppView {
+
+ @Override protected void preHead(Page.HTML<_> html) {
+ commonPreHead(html);
+ set(DATATABLES_ID, "tasks");
+ set(initID(ACCORDION, "nav"), "{autoHeight:false, active:2}");
+ set(initID(DATATABLES, "tasks"), tasksTableInit());
+ setTableStyles(html, "tasks");
+ }
+
+ @Override protected Class<? extends SubView> content() {
+ return TasksBlock.class;
+ }
+
+ private String tasksTableInit() {
+ return tableInit().
+ append(",aoColumns:[{sType:'title-numeric'},{sType:'title-numeric',").
+ append("bSearchable:false},null,{sType:'title-numeric'},").
+ append("{sType:'title-numeric'},{sType:'title-numeric'}]}").toString();
+ }
+}
Added: hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/Times.java
URL: http://svn.apache.org/viewvc/hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/Times.java?rev=1082677&view=auto
==============================================================================
--- hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/Times.java (added)
+++ hadoop/mapreduce/branches/MR-279/mr-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/webapp/Times.java Thu Mar 17 20:21:13 2011
@@ -0,0 +1,29 @@
+/**
+* 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.mapreduce.v2.app.webapp;
+
+final class Times {
+
+ static long elapsed(long started, long finished) {
+ if (finished > 0) {
+ return finished - started;
+ }
+ return System.currentTimeMillis() - started;
+ }
+}