diff --git a/hadoop-yarn-project/CHANGES.txt b/hadoop-yarn-project/CHANGES.txt index 29c8b8049c7..ef0f0d466f4 100644 --- a/hadoop-yarn-project/CHANGES.txt +++ b/hadoop-yarn-project/CHANGES.txt @@ -93,6 +93,9 @@ Release 2.3.0 - UNRELEASED asynchronously to work around potential slowness in state-store. (Omkar Vinit Joshi via vinodkv) + YARN-584. In scheduler web UIs, queues unexpand on refresh. (Harshit + Daga via Sandy Ryza) + OPTIMIZATIONS BUG FIXES diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/CapacitySchedulerPage.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/CapacitySchedulerPage.java index a3e48b31557..a4600d8ca05 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/CapacitySchedulerPage.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/CapacitySchedulerPage.java @@ -249,7 +249,8 @@ class CapacitySchedulerPage extends RmView { _("$(function() {", " $('#cs a span').addClass('ui-corner-all').css('position', 'absolute');", " $('#cs').bind('loaded.jstree', function (e, data) {", - " data.inst.open_node('#pq', true);", + " var callback = { call:reopenQueryNodes }", + " data.inst.open_node('#pq', callback);", " }).", " jstree({", " core: { animation: 188, html_titles: true },", @@ -265,7 +266,8 @@ class CapacitySchedulerPage extends RmView { " $('#apps').dataTable().fnFilter(q, 3, true);", " });", " $('#cs').show();", - "});")._(); + "});")._(). + _(SchedulerPageUtil.QueueBlockUtil.class); } @Override protected Class content() { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/FairSchedulerPage.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/FairSchedulerPage.java index 209a0478dba..73ab42005de 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/FairSchedulerPage.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/FairSchedulerPage.java @@ -201,7 +201,8 @@ public class FairSchedulerPage extends RmView { _("$(function() {", " $('#cs a span').addClass('ui-corner-all').css('position', 'absolute');", " $('#cs').bind('loaded.jstree', function (e, data) {", - " data.inst.open_node('#pq', true);", + " var callback = { call:reopenQueryNodes }", + " data.inst.open_node('#pq', callback);", " }).", " jstree({", " core: { animation: 188, html_titles: true },", @@ -217,7 +218,8 @@ public class FairSchedulerPage extends RmView { " $('#apps').dataTable().fnFilter(q, 3, true);", " });", " $('#cs').show();", - "});")._(); + "});")._(). + _(SchedulerPageUtil.QueueBlockUtil.class); } @Override protected Class content() { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/SchedulerPageUtil.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/SchedulerPageUtil.java new file mode 100644 index 00000000000..99c05656f3a --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/SchedulerPageUtil.java @@ -0,0 +1,177 @@ +/** +* 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.yarn.server.resourcemanager.webapp; + +import org.apache.hadoop.yarn.webapp.view.HtmlBlock; + +public class SchedulerPageUtil { + + static class QueueBlockUtil extends HtmlBlock { + + private void reopenQueue(Block html) { + html. + script().$type("text/javascript"). + _("function reopenQueryNodes() {", + " var currentParam = window.location.href.split('?');", + " var tmpCurrentParam = currentParam;", + " var queryQueuesString = '';", + " if (tmpCurrentParam.length > 1) {", + " // openQueues=q1#q2¶m1=value1¶m2=value2", + " tmpCurrentParam = tmpCurrentParam[1];", + " if (tmpCurrentParam.indexOf('openQueues=') != -1 ) {", + " tmpCurrentParam = tmpCurrentParam.split('openQueues=')[1].split('&')[0];", + " queryQueuesString = tmpCurrentParam;", + " }", + " }", + " if (queryQueuesString != '') {", + " queueArray = queryQueuesString.split('#');", + " $('#cs .q').each(function() {", + " var name = $(this).html();", + " if (name != 'root' && $.inArray(name, queueArray) != -1) {", + " $(this).closest('li').removeClass('jstree-closed').addClass('jstree-open'); ", + " }", + " });", + " }", + " $('#cs').bind( {", + " 'open_node.jstree' :function(e, data) { storeExpandedQueue(e, data); },", + " 'close_node.jstree':function(e, data) { storeExpandedQueue(e, data); }", + " });", + "}")._(); + } + + private void storeExpandedQueue (Block html) { + html. + script().$type("text/javascript"). + _("function storeExpandedQueue(e, data) {", + " var OPEN_QUEUES = 'openQueues';", + " var ACTION_OPEN = 'open';", + " var ACTION_CLOSED = 'closed';", + " var $li = $(data.args[0]);", + " var action = ACTION_CLOSED; //closed or open", + " var queueName = ''", + " if ($li.hasClass('jstree-open')) {", + " action=ACTION_OPEN;", + " }", + " queueName = $li.find('.q').html();", + " // http://localhost:8088/cluster/scheduler?openQueues=q1#q2¶m1=value1¶m2=value2 ", + " // ==> [http://localhost:8088/cluster/scheduler , openQueues=q1#q2¶m1=value1¶m2=value2]", + " var currentParam = window.location.href.split('?');", + " var tmpCurrentParam = currentParam;", + " var queryString = '';", + " if (tmpCurrentParam.length > 1) {", + " // openQueues=q1#q2¶m1=value1¶m2=value2", + " tmpCurrentParam = tmpCurrentParam[1];", + " currentParam = tmpCurrentParam;", + " tmpCurrentParam = tmpCurrentParam.split('&');", + " var len = tmpCurrentParam.length;", + " var paramExist = false;", + " if (len > 1) { // Currently no query param are present but in future if any are added for that handling it now", + " queryString = '';", + " for (var i = 0 ; i < len ; i++) { // searching for param openQueues", + " if (tmpCurrentParam[i].substr(0,11) == OPEN_QUEUES + '=') {", + " if (action == ACTION_OPEN) {", + " tmpCurrentParam[i] = addQueueName(tmpCurrentParam[i],queueName);", + " }", + " else if (action == ACTION_CLOSED) {", + " tmpCurrentParam[i] = removeQueueName(tmpCurrentParam[i] , queueName);", + " }", + " paramExist = true;", + " }", + " if (i > 0) {", + " queryString += '&';", + " }", + " queryString += tmpCurrentParam[i];", + " }", + " // If in existing query string OPEN_QUEUES param is not present", + " if (action == ACTION_OPEN && !paramExist) {", + " queryString = currentParam + '&' + OPEN_QUEUES + '=' + queueName;", + " }", + " } ", + " // Only one param is present in current query string", + " else {", + " tmpCurrentParam=tmpCurrentParam[0];", + " // checking if the only param present in query string is OPEN_QUEUES or not and making queryString accordingly", + " if (tmpCurrentParam.substr(0,11) == OPEN_QUEUES + '=') {", + " if (action == ACTION_OPEN) {", + " queryString = addQueueName(tmpCurrentParam,queueName);", + " }", + " else if (action == ACTION_CLOSED) {", + " queryString = removeQueueName(tmpCurrentParam , queueName);", + " }", + " }", + " else {", + " if (action == ACTION_OPEN) {", + " queryString = tmpCurrentParam + '&' + OPEN_QUEUES + '=' + queueName;", + " }", + " }", + " }", + " } else {", + " if (action == ACTION_OPEN) {", + " tmpCurrentParam = '';", + " currentParam = tmpCurrentParam;", + " queryString = OPEN_QUEUES+'='+queueName;", + " }", + " }", + " if (queryString != '') {", + " queryString = '?' + queryString;", + " }", + " var url = window.location.protocol + '//' + window.location.host + window.location.pathname + queryString;", + " window.history.pushState( { path : url }, '', url);", + "};", + "", + "function removeQueueName(queryString, queueName) {", + " var index = queryString.indexOf(queueName);", + " // Finding if queue is present in query param then only remove it", + " if (index != -1) {", + " // removing openQueues=", + " var tmp = queryString.substr(11, queryString.length);", + " tmp = tmp.split('#');", + " var len = tmp.length;", + " var newQueryString = '';", + " for (var i = 0 ; i < len ; i++) {", + " if (tmp[i] != queueName) {", + " if (newQueryString != '') {", + " newQueryString += '#';", + " }", + " newQueryString += tmp[i];", + " }", + " }", + " queryString = newQueryString;", + " if (newQueryString != '') {", + " queryString = 'openQueues=' + newQueryString;", + " }", + " }", + " return queryString;", + "}", + "", + "function addQueueName(queryString, queueName) {", + " queueArray = queryString.split('#');", + " if ($.inArray(queueArray, queueName) == -1) {", + " queryString = queryString + '#' + queueName;", + " }", + " return queryString;", + "}")._(); + } + + @Override protected void render(Block html) { + reopenQueue(html); + storeExpandedQueue(html); + } + } +}