var flower = (function () { "use strict"; /*jslint browser: true */ /*global $, WebSocket, jQuery, Rickshaw */ function on_alert_close(event) { event.preventDefault(); event.stopPropagation(); $(event.target).parent().hide(); } function show_error_alert(message) { $("#alert").removeClass("alert-success").addClass("alert-error"); $("#alert-message").html("Error! " + message); $("#alert").show(); } function show_success_alert(message) { $("#alert").removeClass("alert-error").addClass("alert-success"); $("#alert-message").html("Success! " + message); $("#alert").show(); } function get_selected_workers() { return $('#workers-table tr').has('td.is_selected > input:checked'); } function select_all_workers() { $('#workers-table td.is_selected > input').filter(':not(:checked)').click(); } function select_none_workers() { $('#workers-table td.is_selected > input:checked').click(); } function toggle_selected_workers(event) { var $checkbox = $('#select-workers-toggler'); $checkbox.is(':checked') ? select_all_workers() : select_none_workers(); } function shutdown_selected(event) { var $selected_workes = get_selected_workers(); /* atomic would be better with list of ids (not-names) */ $selected_workes.each(function () { var $worker = $(this), worker_name = $worker.attr('id'); $.ajax({ type: 'POST', url: url_prefix() + '/api/worker/shutdown/' + worker_name, dataType: 'json', data: { workername: worker_name }, success: function (data) { show_success_alert(data.message); }, error: function (data) { show_error_alert(data.responseText); } }); }); } function restart_selected(event) { var $selected_workes = get_selected_workers(); /* atomic would be better with list of ids (not-names) */ $selected_workes.each(function () { var $worker = $(this), worker_name = $worker.attr('id'); $.ajax({ type: 'POST', url: url_prefix() + '/api/worker/pool/restart/' + worker_name, dataType: 'json', data: { workername: worker_name }, success: function (data) { show_success_alert(data.message); }, error: function (data) { show_error_alert(data.responseText); } }); }); } function on_pool_grow(event) { event.preventDefault(); event.stopPropagation(); var workername = $('#workername').text(), grow_size = $('#pool-size option:selected').html(); $.ajax({ type: 'POST', url: url_prefix() + '/api/worker/pool/grow/' + workername, dataType: 'json', data: { 'workername': workername, 'n': grow_size, }, success: function (data) { show_success_alert(data.message); }, error: function (data) { show_error_alert(data.responseText); } }); } function on_pool_shrink(event) { event.preventDefault(); event.stopPropagation(); var workername = $('#workername').text(), shrink_size = $('#pool-size option:selected').html(); $.ajax({ type: 'POST', url: url_prefix() + '/api/worker/pool/shrink/' + workername, dataType: 'json', data: { 'workername': workername, 'n': shrink_size, }, success: function (data) { show_success_alert(data.message); }, error: function (data) { show_error_alert(data.responseText); } }); } function on_pool_autoscale(event) { event.preventDefault(); event.stopPropagation(); var workername = $('#workername').text(), min = $('#min-autoscale').val(), max = $('#max-autoscale').val(); $.ajax({ type: 'POST', url: url_prefix() + '/api/worker/pool/autoscale/' + workername, dataType: 'json', data: { 'workername': workername, 'min': min, 'max': max, }, success: function (data) { show_success_alert(data.message); }, error: function (data) { show_error_alert(data.responseText); } }); } function on_add_consumer(event) { event.preventDefault(); event.stopPropagation(); var workername = $('#workername').text(), queue = $('#add-consumer-name').val(); $.ajax({ type: 'POST', url: url_prefix() + '/api/worker/queue/add-consumer/' + workername, dataType: 'json', data: { 'workername': workername, 'queue': queue, }, success: function (data) { show_success_alert(data.message); setTimeout(function () { $('#tab-queues').load(url_prefix() + '/worker/' + workername + ' #tab-queues').fadeIn('show'); }, 10000); }, error: function (data) { show_error_alert(data.responseText); } }); } function on_cancel_consumer(event) { event.preventDefault(); event.stopPropagation(); var workername = $('#workername').text(), queue = $(event.target).closest("tr").children("td:eq(0)").text(); $.ajax({ type: 'POST', url: url_prefix() + '/api/worker/queue/cancel-consumer/' + workername, dataType: 'json', data: { 'workername': workername, 'queue': queue, }, success: function (data) { show_success_alert(data.message); setTimeout(function () { $('#tab-queues').load(url_prefix() + '/worker/' + workername + ' #tab-queues').fadeIn('show'); }, 10000); }, error: function (data) { show_error_alert(data.responseText); } }); } function on_task_timeout(event) { event.preventDefault(); event.stopPropagation(); var workername = $('#workername').text(), taskname = $(event.target).closest("tr").children("td:eq(0)").text(), type = $(event.target).html().toLowerCase(), timeout = $(event.target).siblings().closest("input").val(), data = {}; taskname = taskname.split(' ')[0]; // removes [rate_limit=xxx] console.log(type); data.taskname = taskname; data[type] = timeout; $.ajax({ type: 'POST', url: url_prefix() + '/api/task/timeout/' + workername, dataType: 'json', data: data, success: function (data) { show_success_alert(data.message); }, error: function (data) { show_error_alert(data.responseText); } }); } function on_task_rate_limit(event) { event.preventDefault(); event.stopPropagation(); var workername = $('#workername').text(), taskname = $(event.target).closest("tr").children("td:eq(0)").text(), ratelimit = $(event.target).prev().val(); taskname = taskname.split(' ')[0]; // removes [rate_limit=xxx] $.ajax({ type: 'POST', url: url_prefix() + '/api/task/rate-limit/' + workername, dataType: 'json', data: { 'taskname': taskname, 'ratelimit': ratelimit, }, success: function (data) { show_success_alert(data.message); setTimeout(function () { $('#tab-limits').load(url_prefix() + '/worker/' + workername + ' #tab-limits').fadeIn('show'); }, 10000); }, error: function (data) { show_error_alert(data.responseText); } }); } function on_task_revoke(event) { event.preventDefault(); event.stopPropagation(); var taskid = $('#taskid').text(); $.ajax({ type: 'POST', url: url_prefix() + '/api/task/revoke/' + taskid, dataType: 'json', data: { 'terminate': false, }, success: function (data) { show_success_alert(data.message); }, error: function (data) { show_error_alert(data.responseText); } }); } function on_task_terminate(event) { event.preventDefault(); event.stopPropagation(); var taskid = $('#taskid').text(); $.ajax({ type: 'POST', url: url_prefix() + '/api/task/revoke/' + taskid, dataType: 'json', data: { 'terminate': true, }, success: function (data) { show_success_alert(data.message); }, error: function (data) { show_error_alert(data.responseText); } }); } function on_workers_table_update(update) { $.each(update, function (name) { var id = encodeURIComponent(name), sel = id.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/%@])/g,'\\$1'), tr = $('#' + sel); if (tr.length === 0) { $('#workers-table-row').clone().removeClass('hidden').attr('id', id).appendTo('tbody'); tr = $('#' + sel); tr.children('td').children('a').attr('href', url_prefix() + '/worker/' + name).text(name); } var stat = tr.children('td:eq(2)').children(), concurrency = tr.children('td:eq(3)'), completed_tasks = tr.children('td:eq(4)'), running_tasks = tr.children('td:eq(5)'), queues = tr.children('td:eq(6)'); stat.text($(this).attr('status') ? "Online" : "Offline"); stat.removeClass("label-success label-important"); stat.addClass($(this).attr('status') ? "label-success" : "label-important"); concurrency.text($(this).attr('concurrency')); completed_tasks.text($(this).attr('completed_tasks')); running_tasks.text($(this).attr('running_tasks')); queues.text($(this).attr('queues').toString().replace(/,/g, ', ')); }); } function on_cancel_task_filter(event) { event.preventDefault(); event.stopPropagation(); $('#task-filter-form').each(function () { $(this).find('SELECT').val(''); }); $('#task-filter-form').submit(); } function create_graph(data, id, width, height) { id = id || ''; width = width || 700; height = height || 400; var name, seriesData = []; for (name in data) { seriesData.push({name: name}); } var palette = new Rickshaw.Color.Palette({scheme: 'colorwheel'}); var graph = new Rickshaw.Graph({ element: document.getElementById("chart" + id), width: width, height: height, renderer: 'stack', series: new Rickshaw.Series(seriesData, palette), maxDataPoints: 10000, }); var ticksTreatment = 'glow'; var xAxis = new Rickshaw.Graph.Axis.Time({ graph: graph, ticksTreatment: ticksTreatment, }); xAxis.render(); var yAxis = new Rickshaw.Graph.Axis.Y({ graph: graph, tickFormat: Rickshaw.Fixtures.Number.formatKMBT, ticksTreatment: ticksTreatment }); yAxis.render(); var slider = new Rickshaw.Graph.RangeSlider({ graph: graph, element: $('#slider' + id) }); var hoverDetail = new Rickshaw.Graph.HoverDetail({ graph: graph }); var legend = new Rickshaw.Graph.Legend({ graph: graph, element: document.getElementById('legend' + id) }); var shelving = new Rickshaw.Graph.Behavior.Series.Toggle({ graph: graph, legend: legend }); var order = new Rickshaw.Graph.Behavior.Series.Order({ graph: graph, legend: legend }); var highlighter = new Rickshaw.Graph.Behavior.Series.Highlight({ graph: graph, legend: legend }); legend.shelving = shelving; graph.series.legend = legend; graph.render(); return graph; } function update_graph(graph, url, lastquery) { $.ajax({ type: 'GET', url: url, data: {lastquery: lastquery}, success: function (data) { graph.series.addData(data); graph.update(); }, }); } function current_unix_time() { var now = new Date(); return Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds())/1000; } function url_prefix() { // prefix is initialized in base.html if (prefix) { return '/' + prefix; } return ''; } $.urlParam = function(name){ var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href); return results && results[1] || 0; } $(document).ready(function () { if ($.inArray($(location).attr('pathname'), [url_prefix(), url_prefix() + '/workers'])) { var host = $(location).attr('host'), protocol = $(location).attr('protocol') == 'http:' ? 'ws://' : 'wss://', ws = new WebSocket(protocol + host + url_prefix() + "/update-workers"); ws.onmessage = function (event) { var update = $.parseJSON(event.data); on_workers_table_update(update); }; } //https://github.com/twitter/bootstrap/issues/1768 var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); // Make bootstrap tabs persistent $(document).ready(function () { if (location.hash !== '') { $('a[href="' + location.hash + '"]').tab('show'); } $('a[data-toggle="tab"]').on('shown', function (e) { location.hash = $(e.target).attr('href').substr(1); }); }); if ($(location).attr('pathname') === url_prefix() + '/monitor') { var sts = current_unix_time(), fts = current_unix_time(), tts = current_unix_time(), updateinterval = parseInt($.urlParam('updateInterval')) || 3000, succeeded_graph = null, failed_graph = null, time_graph = null, broker_graph = null; $.ajax({ type: 'GET', url: url_prefix() + '/monitor/succeeded-tasks', data: {lastquery: current_unix_time()}, success: function (data) { succeeded_graph = create_graph(data, '-succeeded'); succeeded_graph.update(); succeeded_graph.series.setTimeInterval(updateinterval); setInterval(function () { update_graph(succeeded_graph, url_prefix() + '/monitor/succeeded-tasks', sts); sts = current_unix_time(); }, updateinterval); }, }); $.ajax({ type: 'GET', url: url_prefix() + '/monitor/completion-time', data: {lastquery: current_unix_time()}, success: function (data) { time_graph = create_graph(data, '-time'); time_graph.update(); time_graph.series.setTimeInterval(updateinterval); setInterval(function () { update_graph(time_graph, url_prefix() + '/monitor/completion-time', tts); tts = current_unix_time(); }, updateinterval); }, }); $.ajax({ type: 'GET', url: url_prefix() + '/monitor/failed-tasks', data: {lastquery: current_unix_time()}, success: function (data) { failed_graph = create_graph(data, '-failed'); failed_graph.update(); failed_graph.series.setTimeInterval(updateinterval); setInterval(function () { update_graph(failed_graph, url_prefix() + '/monitor/failed-tasks', fts); fts = current_unix_time(); }, updateinterval); }, }); $.ajax({ type: 'GET', url: url_prefix() + '/monitor/broker', success: function (data) { broker_graph = create_graph(data, '-broker'); broker_graph.update(); broker_graph.series.setTimeInterval(updateinterval); setInterval(function () { update_graph(broker_graph, url_prefix() + '/monitor/broker'); }, updateinterval); }, }); } }); return { toggle_selected_workers: toggle_selected_workers, select_all_workers: select_all_workers, select_none_workers: select_none_workers, shutdown_selected: shutdown_selected, restart_selected: restart_selected, on_alert_close: on_alert_close, on_pool_grow: on_pool_grow, on_pool_shrink: on_pool_shrink, on_pool_autoscale: on_pool_autoscale, on_add_consumer: on_add_consumer, on_cancel_consumer: on_cancel_consumer, on_task_timeout: on_task_timeout, on_task_rate_limit: on_task_rate_limit, on_cancel_task_filter: on_cancel_task_filter, on_task_revoke: on_task_revoke, on_task_terminate: on_task_terminate, }; }(jQuery));