blob: 523554318573e04fad49d2166c3fb1427b4be509 [file] [log] [blame]
/*
* 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.
*/
define([
"jquery", "underscore", "backbone", "moment", "view/viewutils",
"model/server-extended-status",
"text!tpl/home/ha-summary.html"
], function ($, _, Backbone, moment, ViewUtils, serverStatus, HASummaryHtml) {
var template = _.template(HASummaryHtml);
var nodeRowTemplate = _.template(
"<tr>" +
"<td>" +
"<% if (nodeUri && !isTerminated) { %><a href='<%= nodeUri %>'><%= nodeId %></a><% } else { %><%= nodeId %><% } %>" +
"<% if (isSelf) { %><span class='pull-right badge badge-success'>this</span><% } %>" +
"</td>" +
"<td><% if (isPretendMaster) {%>EX-MASTER<%} else {%><%= status %><%} if (isStale) { %> (stale)<% } %></td>" +
"<td><%= timestampDisplayPrefix %><span class='timestamp' data-timestamp='<%= timestamp %>'><%= timestampDisplay %><span><%= timestampDisplaySuffix %></td>" +
"</tr>");
var noServers = "<tr><td colspan='3'><i>Failed to load data of servers</i></td></tr>";
var waitingServers = "<tr><td colspan='3'><i>Waiting on detail for servers...</i></td></tr>";
var HASummaryView = Backbone.View.extend({
initialize: function() {
_.bindAll(this);
this.updateTimestampCallback = setInterval(this.updateTimestamps, 1000);
this.listenTo(serverStatus, "change", this.renderNodeStatus);
},
beforeClose: function() {
clearInterval(this.updateTimestampCallback);
this.stopListening();
},
updateNow: function() {
serverStatus.fetch();
},
render: function() {
this.$el.html(template());
this.renderNodeStatus();
return this;
},
renderNodeStatus: function() {
var $target = this.$(".ha-summary-table-body");
if (!serverStatus.loaded) {
$target.html(waitingServers);
return;
}
var serverHa = serverStatus.get("ha") || {};
var master = serverHa.masterId,
self = serverHa.ownId,
nodes = serverHa.nodes;
// undefined check just in case server returns something odd
if (nodes == undefined || _.isEmpty(nodes)) {
$target.html(noServers);
return;
}
$target.empty();
var masterTimestamp;
_.each(nodes, function (n) {
if (n.nodeId == master && n.remoteTimestamp) {
masterTimestamp = n.remoteTimestamp;
}
});
_.each(nodes, function (n) {
var node = _.clone(n);
node.timestampDisplayPrefix = "";
node.timestampDisplaySuffix = "";
if (node['remoteTimestamp']) {
node.timestamp = node.remoteTimestamp;
} else {
node.timestamp = node.localTimestamp;
node.timestampDisplaySuffix = " (local)";
}
if (node.timestamp >= moment().utc() + 10*1000) {
// if server reports time significantly in future, report this, with no timestampe
node.timestampDisplayPrefix = "server clock in future by "+
moment.duration(moment(node.timestamp).diff(moment())).humanize();
node.timestamp = "";
node.timestampDisplay = "";
} else {
// else use timestamp
if (node.timestamp >= moment().utc()) {
// but if just a little bit in future, backdate to show "a few seconds ago"
node.timestamp = moment().utc()-1;
}
node.timestampDisplay = moment(node.timestamp).fromNow();
}
node.isSelf = node.nodeId == self;
node.isMaster = self == master;
if (node.status == "TERMINATED") {
node.isTerminated = true;
node.isPretendMaster = false;
node.isStale = false;
} else {
node.isTerminated = false;
node.isPretendMaster = (!node.isMaster && node.status == "MASTER" && master != node.nodeId);
node.isStale = (masterTimestamp && node.timestamp + 30*1000 < masterTimestamp);
}
$target.append(nodeRowTemplate(node));
});
},
updateTimestamps: function() {
this.$(".timestamp").each(function(index, t) {
t = $(t);
var timestamp = t.data("timestamp");
t.html(_.escape(moment(timestamp).fromNow()));
});
}
});
return HASummaryView;
});