blob: a0eac8960a3da5898594f415b063ada92d77a7ea [file]
/**
* Licensed 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.
*/
var Task = new Class({
data: {},
initialize: function(taskId, taskType) {
this.taskType = taskType
this.taskId = taskId
this.visible = false
this.setElement()
},
// task[active.task_id.processes.waiting]
taskStr: function(components) {
return 'task[' + ([this.taskType, this.taskId].append(components).join()) + ']'
},
transitionElement: function(dom_id, newval) {
if (!$(dom_id)) {
// alert('could not find dom_id' + dom_id)
return
}
curval = $(dom_id).innerHTML
// handle specialcases
newval = this.translateElement(dom_id, newval)
if (newval != curval) {
$(dom_id).innerHTML = newval
var morphElement = new Fx.Morph(dom_id, {
duration: 'long',
transition: Fx.Transitions.Sine.easeOut
});
morphElement.start({ 'color': ["#00FF00", "#222222"]})
}
},
applyUpdate: function(update) {
this.data = update
this.updateElement()
},
/*
TODO(wickman) Instead do the 2-3 necessary transition functions, then make
a schema that maps attributes to the appropriate transition function.
*/
translateElement: function(dom_id, value) {
if (dom_id === this.taskStr(['processes', 'running']) ||
dom_id === this.taskStr(['processes', 'waiting']) ||
dom_id === this.taskStr(['processes', 'success']) ||
dom_id === this.taskStr(['processes', 'failed'])) {
return value.length
}
if (dom_id == this.taskStr(['resource_consumption', 'cpu'])) {
if (value) {
return value.toFixed(2)
}
}
return value
},
/*
TODO(wickman) Ditto to above.
*/
updateElement: function() {
for (prefix_attr in this.data) {
if (this.data.hasOwnProperty(prefix_attr)) {
if (prefix_attr == "task_id") {
this.transitionElement(this.taskStr([prefix_attr]), this.translateUid(this.data[prefix_attr]))
} else if (instanceOf(this.data[prefix_attr], String) || instanceOf(this.data[prefix_attr], Number)) {
this.transitionElement(this.taskStr([prefix_attr]), this.data[prefix_attr])
} else if (instanceOf(this.data[prefix_attr], Object)) {
for (suffix_attr in this.data[prefix_attr])
if (this.data[prefix_attr].hasOwnProperty(suffix_attr))
this.transitionElement(this.taskStr([prefix_attr, suffix_attr]),
this.data[prefix_attr][suffix_attr])
}
}
}
},
translateUid: function(taskId) {
return "<a href='/task/" + taskId + "'>" + taskId + "</a>"
},
setElement: function() {
this.element = new Element('tr', {
'id': 'task[' + this.taskType + '][' + this.taskId + ']'}).adopt(
new Element('td', { 'id': this.taskStr(['task_id']), 'html': this.translateUid(this.taskId)}),
new Element('td', { 'id': this.taskStr(['name']) }),
new Element('td', { 'id': this.taskStr(['resource_consumption', 'cpu']) }),
new Element('td', { 'id': this.taskStr(['resource_consumption', 'ram']) }),
new Element('td', { 'id': this.taskStr(['resource_consumption', 'disk']) }),
new Element('td', { 'id': this.taskStr(['processes', 'waiting']) }),
new Element('td', { 'id': this.taskStr(['processes', 'running']) }),
new Element('td', { 'id': this.taskStr(['processes', 'success']) }),
new Element('td', { 'id': this.taskStr(['processes', 'failed']) }))
}
})
var TableManager = new Class({
activeTasks: {},
visibleChildren: [],
initialize: function(tableType) {
this.tableType = tableType
this.setElement()
this.getChildren()
this.startPolling()
},
setElement: function() {
this.element = new Element('table', { 'id': 'table[' + this.tableType + ']', 'class': 'common-table zebra-striped', 'cellpadding': '0' })
this.element.adopt(
new Element('thead').
adopt(new Element('tr', { 'id': 'task[' + this.tableType + '][superheader]', 'class': 'meta-headers' })
.adopt(new Element('th', { 'html': "", 'colspan': 2 }),
new Element('th', { 'html': "consumed", 'colspan': 3 }),
new Element('th', { 'html': "processes", 'colspan': 4 })
)
)
.adopt(new Element('tr', { 'id': 'task[' + this.tableType + '][header]' })
.adopt(new Element('th', { 'id': 'task[' + this.tableType + '][header][task_id]', 'html': "task_id" }),
new Element('th', { 'id': 'task[' + this.tableType + '][header][name]', 'html': "name" }),
new Element('th', { 'id': 'task[' + this.tableType + '][header][resource_consumption][cpu]', 'html': "cpu" }),
new Element('th', { 'id': 'task[' + this.tableType + '][header][resource_consumption][ram]', 'html': "ram" }),
new Element('th', { 'id': 'task[' + this.tableType + '][header][resource_consumption][disk]','html': "disk" }),
new Element('th', { 'id': 'task[' + this.tableType + '][header][processes][waiting]', 'html': "waiting" }),
new Element('th', { 'id': 'task[' + this.tableType + '][header][processes][running]', 'html': "running"}),
new Element('th', { 'id': 'task[' + this.tableType + '][header][processes][success]', 'html': "success" }),
new Element('th', { 'id': 'task[' + this.tableType + '][header][processes][failed]', 'html': "failed" })
)
)
)
this.tbody = new Element('tbody', { 'id': this.tableType + '_tbody' })
this.element.adopt(this.tbody)
},
toElement: function() {
return this.element
},
startPolling: function() {
this.taskIdPoller = setInterval(this.tableType + 'TableManager.getChildren();', 2500)
this.dataPoller = setInterval(this.tableType + 'TableManager.refreshVisibleChildren();', 5300)
},
getChildren: function() {
new Request.JSON({
'url': '/j/task_ids/' + this.tableType + '/-20',
'method': 'get',
'onComplete': function(response) {
if (response) {
var newChildren = Array.from(response.task_ids)
this.visibleChildren = newChildren
// first set all children to invisible
for (taskId in this.activeTasks) {
this.activeTasks[taskId].visible = false
}
// set new children visible
for (var k = 0; k < newChildren.length; k++) {
if (!(newChildren[k] in this.activeTasks)) {
this.activeTasks[newChildren[k]] = new Task(newChildren[k], this.tableType)
}
this.activeTasks[newChildren[k]].visible = true
}
// clear then adopt them
while (this.tbody.childNodes.length > 0)
this.tbody.removeChild(this.tbody.firstChild);
for (var k = 0; k < newChildren.length; k++)
this.tbody.adopt(this.activeTasks[newChildren[k]].element)
} else {
clearInterval(this.taskIdPoller)
}
}.bind(this)
}).send()
},
refreshVisibleChildren: function() {
// first get visible children
new Request.JSON({
'url': '/j/task',
'method': 'get',
'data': { 'task_id': this.visibleChildren.join() },
'onComplete': function(response) {
if (response) {
if (!response) return;
for (taskId in response) {
if (response.hasOwnProperty(taskId))
this.activeTasks[taskId].applyUpdate(response[taskId])
}
} else {
clearInterval(this.dataPoller)
}
}.bind(this)
}).send()
},
})