98 lines
4.5 KiB
JavaScript
98 lines
4.5 KiB
JavaScript
// Define an InstructorTaskProgress object for updating a table on the instructor
|
|
// dashboard that shows the current background tasks that are currently running
|
|
// for the instructor's course. Any tasks that were running when the page is
|
|
// first displayed are passed in as instructor_tasks, and populate the "Pending Instructor
|
|
// Task" table. The InstructorTaskProgress is bound to this table, and periodically
|
|
// polls the LMS to see if any of the tasks has completed. Once a task is complete,
|
|
// it is not included in any further polling.
|
|
|
|
(function() {
|
|
var __bind = function(fn, me) { return function() { return fn.apply(me, arguments); }; };
|
|
|
|
this.InstructorTaskProgress = (function() {
|
|
function InstructorTaskProgress(element) {
|
|
this.update_progress = __bind(this.update_progress, this);
|
|
this.get_status = __bind(this.get_status, this);
|
|
this.element = element;
|
|
this.entries = $(element).find('.task-progress-entry');
|
|
if (window.queuePollerID) {
|
|
window.clearTimeout(window.queuePollerID);
|
|
}
|
|
// Hardcode the initial delay before the first refresh to one second:
|
|
window.queuePollerID = window.setTimeout(this.get_status, 1000);
|
|
}
|
|
|
|
InstructorTaskProgress.prototype.$ = function(selector) {
|
|
return $(selector, this.element);
|
|
};
|
|
|
|
InstructorTaskProgress.prototype.update_progress = function(response) {
|
|
var _this = this;
|
|
// Response should be a dict with an entry for each requested task_id,
|
|
// with a "task-state" and "in_progress" key and optionally a "message"
|
|
// and a "task_progress.duration" key.
|
|
var something_in_progress = false;
|
|
for (task_id in response) {
|
|
var task_dict = response[task_id];
|
|
// find the corresponding entry, and update it:
|
|
entry = $(_this.element).find('[data-task-id="' + task_id + '"]');
|
|
entry.find('.task-state').text(task_dict.task_state);
|
|
var duration_value = (task_dict.task_progress && task_dict.task_progress.duration_ms
|
|
&& Math.round(task_dict.task_progress.duration_ms / 1000)) || 'unknown';
|
|
entry.find('.task-duration').text(duration_value);
|
|
var progress_value = task_dict.message || '';
|
|
entry.find('.task-progress').text(progress_value);
|
|
// if the task is complete, then change the entry so it won't
|
|
// be queried again. Otherwise set a flag.
|
|
if (task_dict.in_progress === true) {
|
|
something_in_progress = true;
|
|
} else {
|
|
entry.data('inProgress', 'False');
|
|
}
|
|
}
|
|
|
|
// if some entries are still incomplete, then repoll:
|
|
// Hardcode the refresh interval to be every five seconds.
|
|
// TODO: allow the refresh interval to be set. (And if it is disabled,
|
|
// then don't set the timeout at all.)
|
|
if (something_in_progress) {
|
|
window.queuePollerID = window.setTimeout(_this.get_status, 5000);
|
|
} else {
|
|
delete window.queuePollerID;
|
|
}
|
|
};
|
|
|
|
InstructorTaskProgress.prototype.get_status = function() {
|
|
var _this = this;
|
|
var task_ids = [];
|
|
|
|
// Construct the array of ids to get status for, by
|
|
// including the subset of entries that are still in progress.
|
|
this.entries.each(function(idx, element) {
|
|
var task_id = $(element).data('taskId');
|
|
var in_progress = $(element).data('inProgress');
|
|
if (in_progress = 'True') {
|
|
task_ids.push(task_id);
|
|
}
|
|
});
|
|
|
|
// Make call to get status for these ids.
|
|
// Note that the keyname here ends up with "[]" being appended
|
|
// in the POST parameter that shows up on the Django server.
|
|
// TODO: add error handler.
|
|
var ajax_url = '/instructor_task_status/';
|
|
var data = {task_ids: task_ids};
|
|
$.post(ajax_url, data).done(this.update_progress);
|
|
};
|
|
|
|
return InstructorTaskProgress;
|
|
}());
|
|
}).call(this);
|
|
|
|
// once the page is rendered, create the progress object
|
|
var instructorTaskProgress;
|
|
$(document).ready(function() {
|
|
instructorTaskProgress = new InstructorTaskProgress($('#task-progress-wrapper'));
|
|
});
|
|
|