Skip to content

Commit

Permalink
MDL-67211 Tasks: Front-end to display currently running tasks.
Browse files Browse the repository at this point in the history
Co-authored-by: Sam Marshall <s.marshall@open.ac.uk>
  • Loading branch information
golenkovm and sammarshallou committed Aug 25, 2020
1 parent b465a54 commit 45875f6
Show file tree
Hide file tree
Showing 9 changed files with 373 additions and 2 deletions.
141 changes: 141 additions & 0 deletions admin/tool/task/classes/running_tasks_table.php
@@ -0,0 +1,141 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Running tasks table.
*
* @package tool_task
* @copyright 2019 The Open University
* @copyright 2020 Mikhail Golenkov <golenkovm@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

namespace tool_task;

defined('MOODLE_INTERNAL') || die();

require_once($CFG->libdir . '/tablelib.php');

/**
* Table to display list of running task.
*
* @copyright 2019 The Open University
* @copyright 2020 Mikhail Golenkov <golenkovm@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class running_tasks_table extends \table_sql {

/**
* Constructor for the running tasks table.
*/
public function __construct() {
parent::__construct('runningtasks');

$columnheaders = [
'classname' => get_string('classname', 'tool_task'),
'type' => get_string('tasktype', 'admin'),
'time' => get_string('time'),
'timestarted' => get_string('started', 'tool_task'),
'hostname' => get_string('hostname', 'tool_task'),
'pid' => get_string('pid', 'tool_task'),
];
$this->define_columns(array_keys($columnheaders));
$this->define_headers(array_values($columnheaders));

// The name column is a header.
$this->define_header_column('classname');

// This table is not collapsible.
$this->collapsible(false);

// Allow pagination.
$this->pageable(true);
}

/**
* Query the db. Store results in the table object for use by build_table.
*
* @param int $pagesize size of page for paginated displayed table.
* @param bool $useinitialsbar do you want to use the initials bar. Bar
* will only be used if there is a fullname column defined for the table.
* @throws \dml_exception
*/
public function query_db($pagesize, $useinitialsbar = true) {
$sort = $this->get_sql_sort();
$this->rawdata = \core\task\manager::get_running_tasks($sort);
}

/**
* Format the classname cell.
*
* @param \stdClass $row
* @return string
*/
public function col_classname($row) : string {
$output = $row->classname;
if ($row->type == 'scheduled') {
if (class_exists($row->classname)) {
$task = new $row->classname;
if ($task instanceof \core\task\scheduled_task) {
$output .= \html_writer::tag('div', $task->get_name(), ['class' => 'task-class']);
}
}
} else if ($row->type == 'adhoc') {
$output .= \html_writer::tag('div',
get_string('adhoctaskid', 'tool_task', $row->id), ['class' => 'task-class']);
}
return $output;
}

/**
* Format the type cell.
*
* @param \stdClass $row
* @return string
* @throws \coding_exception
*/
public function col_type($row) : string {
if ($row->type == 'scheduled') {
$output = \html_writer::span(get_string('scheduled', 'tool_task'), 'badge badge-primary');
} else if ($row->type == 'adhoc') {
$output = \html_writer::span(get_string('adhoc', 'tool_task'), 'badge badge-warning');
} else {
// This shouldn't ever happen.
$output = '';
}
return $output;
}

/**
* Format the time cell.
*
* @param \stdClass $row
* @return string
*/
public function col_time($row) : string {
return format_time($row->time);
}

/**
* Format the timestarted cell.
*
* @param \stdClass $row
* @return string
*/
public function col_timestarted($row) : string {
return userdate($row->timestarted);
}
}
8 changes: 8 additions & 0 deletions admin/tool/task/lang/en/tool_task.php
Expand Up @@ -22,6 +22,9 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

$string['adhoc'] = 'Ad-hoc';
$string['adhoctaskid'] = 'Ad-hoc task id: {$a}';
$string['adhoctasks'] = 'Ad-hoc tasks';
$string['asap'] = 'ASAP';
$string['adhocempty'] = 'Ad hoc task queue is empty';
$string['adhocqueuesize'] = 'Ad hoc task queue has {$a} tasks';
Expand All @@ -32,6 +35,7 @@
$string['checkadhocqueue'] = 'Ad hoc task queue';
$string['checkcronrunning'] = 'Cron running';
$string['checkmaxfaildelay'] = 'Tasks max fail delay';
$string['classname'] = 'Class name';
$string['clearfaildelay_confirm'] = 'Are you sure you want to clear the fail delay for task \'{$a}\'? After clearing the delay, the task will run according to its normal schedule.';
$string['component'] = 'Component';
$string['corecomponent'] = 'Core';
Expand All @@ -47,18 +51,22 @@
$string['fromcomponent'] = 'From component: {$a}';
$string['hostname'] = 'Host name';
$string['lastruntime'] = 'Last run';
$string['lastupdated'] = 'Last updated {$a}.';
$string['nextruntime'] = 'Next run';
$string['pid'] = 'PID';
$string['plugindisabled'] = 'Plugin disabled';
$string['pluginname'] = 'Scheduled task configuration';
$string['resettasktodefaults'] = 'Reset task schedule to defaults';
$string['resettasktodefaults_help'] = 'This will discard any local changes and revert the schedule for this task back to its original settings.';
$string['runningtasks'] = 'Tasks running now';
$string['runnow'] = 'Run now';
$string['runagain'] = 'Run again';
$string['runnow_confirm'] = 'Are you sure you want to run this task \'{$a}\' now? The task will run on the web server and may take some time to complete.';
$string['runpattern'] = 'Run pattern';
$string['scheduled'] = 'Scheduled';
$string['scheduledtasks'] = 'Scheduled tasks';
$string['scheduledtaskchangesdisabled'] = 'Modifications to the list of scheduled tasks have been prevented in Moodle configuration';
$string['started'] = 'Started';
$string['taskdisabled'] = 'Task disabled';
$string['taskfailures'] = '{$a} task(s) failing';
$string['tasklogs'] = 'Task logs';
Expand Down
46 changes: 46 additions & 0 deletions admin/tool/task/runningtasks.php
@@ -0,0 +1,46 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Running task admin page.
*
* @package tool_task
* @copyright 2019 The Open University
* @copyright 2020 Mikhail Golenkov <golenkovm@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

require_once(__DIR__ . '/../../../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/tablelib.php');

$pageurl = new \moodle_url('/admin/tool/task/runningtasks.php');
$heading = get_string('runningtasks', 'tool_task');
$PAGE->set_url($pageurl);
$PAGE->set_context(context_system::instance());
$PAGE->set_pagelayout('admin');
$PAGE->set_title($heading);
$PAGE->set_heading($heading);

admin_externalpage_setup('runningtasks');

echo $OUTPUT->header();

$table = new \tool_task\running_tasks_table();
$table->baseurl = $pageurl;
$table->out(100, false);

echo $OUTPUT->footer();
9 changes: 9 additions & 0 deletions admin/tool/task/settings.php
Expand Up @@ -33,4 +33,13 @@
"$CFG->wwwroot/$CFG->admin/tool/task/scheduledtasks.php"
)
);

$ADMIN->add(
'taskconfig',
new admin_externalpage(
'runningtasks',
new lang_string('runningtasks', 'tool_task'),
"$CFG->wwwroot/$CFG->admin/tool/task/runningtasks.php"
)
);
}
3 changes: 2 additions & 1 deletion admin/tool/task/styles.css
@@ -1,4 +1,5 @@
#page-admin-tool-task-scheduledtasks .task-class {
#page-admin-tool-task-scheduledtasks .task-class,
#page-admin-tool-task-runningtasks .task-class {
display: block;
padding: 0 0.5em;
color: #888;
Expand Down
40 changes: 40 additions & 0 deletions admin/tool/task/tests/behat/running_tasks.feature
@@ -0,0 +1,40 @@
@tool @tool_task
Feature: See running scheduled tasks
In order to configure scheduled tasks
As an admin
I need to see if tasks are running

Background:
Given I log in as "admin"

Scenario: If no task is running, I should see the corresponding message
Given I navigate to "Server > Tasks > Tasks running now" in site administration
Then I should see "Nothing to display"

Scenario: If tasks are running, I should see task details
Given the following "tool_task > scheduled tasks" exist:
| classname | seconds | hostname | pid |
| \core\task\automated_backup_task | 121 | c69335460f7f | 1914 |
And the following "tool_task > adhoc tasks" exist:
| classname | seconds | hostname | pid |
| \core\task\asynchronous_backup_task | 7201 | c69335460f7f | 1915 |
| \core\task\asynchronous_restore_task | 172800 | c69335460f7f | 1916 |
And I navigate to "Server > Tasks > Tasks running now" in site administration

# Check the scheduled task details.
Then I should see "Scheduled" in the "\core\task\automated_backup_task" "table_row"
And I should see "2 mins" in the "Automated backups" "table_row"
And I should see "c69335460f7f" in the "Automated backups" "table_row"
And I should see "1914" in the "Automated backups" "table_row"

# Check the "asynchronous_backup_task" adhoc task details.
And I should see "Ad-hoc" in the "\core\task\asynchronous_backup_task" "table_row"
And I should see "2 hours" in the "core\task\asynchronous_backup_task" "table_row"
And I should see "c69335460f7f" in the "core\task\asynchronous_backup_task" "table_row"
And I should see "1915" in the "core\task\asynchronous_backup_task" "table_row"

# Check the "asynchronous_restore_task" adhoc task details.
And I should see "Ad-hoc" in the "\core\task\asynchronous_restore_task" "table_row"
And I should see "2 days" in the "core\task\asynchronous_restore_task" "table_row"
And I should see "c69335460f7f" in the "core\task\asynchronous_restore_task" "table_row"
And I should see "1916" in the "core\task\asynchronous_restore_task" "table_row"
57 changes: 57 additions & 0 deletions admin/tool/task/tests/generator/behat_tool_task_generator.php
@@ -0,0 +1,57 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

/**
* Behat data generator for tool_task.
*
* @package tool_task
* @category test
* @copyright 2020 Mikhail Golenkov <golenkovm@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

defined('MOODLE_INTERNAL') || die();

/**
* Behat data generator for tool_task.
*
* @package tool_task
* @category test
* @copyright 2020 Mikhail Golenkov <golenkovm@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class behat_tool_task_generator extends behat_generator_base {

/**
* Get a list of the entities that can be created.
* @return array entity name => information about how to generate.
*/
protected function get_creatable_entities(): array {
return [
'scheduled tasks' => [
'singular' => 'scheduled task',
'datagenerator' => 'scheduled_tasks',
'required' => ['classname', 'seconds', 'hostname', 'pid'],
],
'adhoc tasks' => [
'singular' => 'adhoc task',
'datagenerator' => 'adhoc_tasks',
'required' => ['classname', 'seconds', 'hostname', 'pid'],
],
];
}
}

0 comments on commit 45875f6

Please sign in to comment.