Skip to content

Commit

Permalink
MDL-67211 Tasks: Add cron_enabled setting.
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 45875f6 commit d7342dc
Show file tree
Hide file tree
Showing 12 changed files with 193 additions and 9 deletions.
9 changes: 9 additions & 0 deletions admin/cli/adhoc_task.php
Expand Up @@ -37,11 +37,13 @@
'showsql' => false,
'showdebugging' => false,
'ignorelimits' => false,
'force' => false,
], [
'h' => 'help',
'e' => 'execute',
'k' => 'keep-alive',
'i' => 'ignorelimits',
'f' => 'force',
]
);

Expand All @@ -61,6 +63,7 @@
-e, --execute Run all queued adhoc tasks
-k, --keep-alive=N Keep this script alive for N seconds and poll for new adhoc tasks
-i --ignorelimits Ignore task_adhoc_concurrency_limit and task_adhoc_max_runtime limits
-f, --force Run even if cron is disabled
Example:
\$sudo -u www-data /usr/bin/php admin/cli/adhoc_task.php --execute
Expand Down Expand Up @@ -92,6 +95,12 @@
if (empty($options['execute'])) {
exit(0);
}

if (!get_config('core', 'cron_enabled') && !$options['force']) {
mtrace('Cron is disabled. Use --force to override.');
exit(1);
}

if (empty($options['keep-alive'])) {
$options['keep-alive'] = 0;
}
Expand Down
111 changes: 105 additions & 6 deletions admin/cli/cron.php
Expand Up @@ -36,14 +36,23 @@

// now get cli options
list($options, $unrecognized) = cli_get_params(
array(
[
'help' => false,
'stop' => false,
),
array(
'list' => false,
'force' => false,
'enable' => false,
'disable' => false,
'disable-wait' => false,
], [
'h' => 'help',
's' => 'stop',
)
'l' => 'list',
'f' => 'force',
'e' => 'enable',
'd' => 'disable',
'w' => 'disable-wait',
]
);

if ($unrecognized) {
Expand All @@ -56,8 +65,13 @@
"Execute periodic cron actions.
Options:
-h, --help Print out this help
-s, --stop Notify all other running cron processes to stop after the current task
-h, --help Print out this help
-s, --stop Notify all other running cron processes to stop after the current task
-l, --list Show the list of currently running tasks and how long they have been running
-f, --force Execute task even if cron is disabled
-e, --enable Enable cron
-d, --disable Disable cron
-w, --disable-wait=600 Disable cron and wait until all tasks finished or fail after N seconds (optional param)
Example:
\$sudo -u www-data /usr/bin/php admin/cli/cron.php
Expand All @@ -74,6 +88,91 @@
die;
}

if ($options['enable']) {
set_config('cron_enabled', 1);
mtrace('Cron has been enabled for the site.');
exit(0);
}

if ($options['disable']) {
set_config('cron_enabled', 0);
\core\task\manager::clear_static_caches();
mtrace('Cron has been disabled for the site.');
exit(0);
}

if ($options['list']) {
$tasks = \core\task\manager::get_running_tasks();
mtrace('The list of currently running tasks:');
$format = "%7s %-12s %-9s %-20s %-52s\n";
printf ($format,
'PID',
'HOST',
'TYPE',
'TIME',
'CLASSNAME'
);
foreach ($tasks as $task) {
printf ($format,
$task->pid,
substr($task->hostname, 0, 12),
$task->type,
format_time(time() - $task->timestarted),
substr($task->classname, 0, 52)
);
}
exit(0);
}

if ($wait = $options['disable-wait']) {
$started = time();
if (true === $wait) {
// Default waiting time.
$waitsec = 600;
} else {
$waitsec = $wait;
$wait = true;
}

set_config('cron_enabled', 0);
\core\task\manager::clear_static_caches();
mtrace('Cron has been disabled for the site.');
mtrace('Allocating '. format_time($waitsec) . ' for the tasks to finish.');

$lastcount = 0;
while ($wait) {
$tasks = \core\task\manager::get_running_tasks();

if (count($tasks) == 0) {
mtrace('');
mtrace('All scheduled and adhoc tasks finished.');
exit(0);
}

if (time() - $started >= $waitsec) {
mtrace('');
mtrace('Wait time ('. format_time($waitsec) . ') elapsed, but ' . count($tasks) . ' task(s) still running.');
mtrace('Exiting with code 1.');
exit(1);
}

if (count($tasks) !== $lastcount) {
mtrace('');
mtrace(count($tasks) . " tasks currently running.", '');
$lastcount = count($tasks);
} else {
mtrace('.', '');
}

sleep(1);
}
}

if (!get_config('core', 'cron_enabled') && !$options['force']) {
mtrace('Cron is disabled. Use --force to override.');
exit(1);
}

\core\local\cli\shutdown::script_supports_graceful_exit();

cron_run();
19 changes: 17 additions & 2 deletions admin/cli/scheduled_task.php
Expand Up @@ -30,8 +30,17 @@
require_once("$CFG->libdir/cronlib.php");

list($options, $unrecognized) = cli_get_params(
array('help' => false, 'list' => false, 'execute' => false, 'showsql' => false, 'showdebugging' => false),
array('h' => 'help')
[
'help' => false,
'list' => false,
'execute' => false,
'showsql' => false,
'showdebugging' => false,
'force' => false,
], [
'h' => 'help',
'f' => 'force',
]
);

if ($unrecognized) {
Expand All @@ -49,6 +58,7 @@
--showsql Show sql queries before they are executed
--showdebugging Show developer level debugging information
-h, --help Print out this help
-f, --force Execute task even if cron is disabled
Example:
\$sudo -u www-data /usr/bin/php admin/cli/scheduled_task.php --execute=\\core\\task\\session_cleanup_task
Expand Down Expand Up @@ -121,6 +131,11 @@
exit(1);
}

if (!get_config('core', 'cron_enabled') && !$options['force']) {
mtrace('Cron is disabled. Use --force to override.');
exit(1);
}

\core\task\manager::scheduled_task_starting($task);

// Increase memory limit.
Expand Down
10 changes: 10 additions & 0 deletions admin/settings/server.php
Expand Up @@ -216,6 +216,16 @@

$ADMIN->add('server', new admin_category('taskconfig', new lang_string('taskadmintitle', 'admin')));
$temp = new admin_settingpage('taskprocessing', new lang_string('taskprocessing','admin'));

$setting = new admin_setting_configcheckbox(
'cron_enabled',
new lang_string('cron_enabled', 'admin'),
new lang_string('cron_enabled_desc', 'admin'),
1
);
$setting->set_updatedcallback('theme_reset_static_caches');
$temp->add($setting);

$temp->add(
new admin_setting_configtext(
'task_scheduled_concurrency_limit',
Expand Down
1 change: 1 addition & 0 deletions admin/tool/task/lang/en/tool_task.php
Expand Up @@ -39,6 +39,7 @@
$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';
$string['crondisabled'] = 'Cron is disabled. No new tasks will be started. The system will not operate properly until it is enabled again.';
$string['cronok'] = 'Cron is running frequently';
$string['default'] = 'Default';
$string['defaultx'] = 'Default: {$a}';
Expand Down
10 changes: 10 additions & 0 deletions admin/tool/task/renderer.php
Expand Up @@ -261,6 +261,16 @@ protected function time_cell(string $current, string $default): html_table_cell
return $cell;
}

/**
* Displays a warning on the page if cron is disabled.
*
* @return string HTML code for information about cron being disabled
* @throws moodle_exception
*/
public function cron_disabled(): string {
return $this->output->notification(get_string('crondisabled', 'tool_task'), 'warning');
}

/**
* Renders a link back to the scheduled tasks page (used from the 'run now' screen).
*
Expand Down
5 changes: 5 additions & 0 deletions admin/tool/task/runningtasks.php
Expand Up @@ -39,6 +39,11 @@

echo $OUTPUT->header();

if (!get_config('core', 'cron_enabled')) {
$renderer = $PAGE->get_renderer('tool_task');
echo $renderer->cron_disabled();
}

$table = new \tool_task\running_tasks_table();
$table->baseurl = $pageurl;
$table->out(100, false);
Expand Down
3 changes: 3 additions & 0 deletions admin/tool/task/scheduledtasks.php
Expand Up @@ -95,6 +95,9 @@

} else {
echo $OUTPUT->header();
if (!get_config('core', 'cron_enabled')) {
echo $renderer->cron_disabled();
}
$tasks = core\task\manager::get_all_scheduled_tasks();
echo $renderer->scheduled_tasks_table($tasks, $lastchanged);
echo $OUTPUT->footer();
Expand Down
20 changes: 20 additions & 0 deletions admin/tool/task/tests/behat/cron_disabled.feature
@@ -0,0 +1,20 @@
@tool @tool_task
Feature: See warning message if cron is disabled
In order to manage scheduled tasks
As a Moodle Administrator
I need to be able to view a warning message if cron is disabled

Background:
Given I log in as "admin"

Scenario: If cron is disabled, I should see the message
When the following config values are set as admin:
| cron_enabled | 0 |
And I navigate to "Server > Tasks > Scheduled tasks" in site administration
Then I should see "Cron is disabled"

Scenario: If cron is enabled, I should not see the message
When the following config values are set as admin:
| cron_enabled | 1 |
And I navigate to "Server > Tasks > Scheduled tasks" in site administration
Then I should not see "Cron is disabled"
2 changes: 2 additions & 0 deletions lang/en/admin.php
Expand Up @@ -424,6 +424,8 @@
$string['creatornewroleid'] = 'Creators\' role in new courses';
$string['creatornewroleid_help'] = 'If the user does not already have the permission to manage the new course, the user is automatically enrolled using this role.';
$string['cron'] = 'Cron';
$string['cron_enabled'] = 'Enable cron';
$string['cron_enabled_desc'] = 'If disabled prevents the system from starting new background tasks. This option is intended for temporary use only, e.g. before a restart. Leaving it off for a long time will prevent important functionality from working.';
$string['cron_help'] = 'The cron.php script runs a number of tasks at different scheduled intervals, such as sending forum post notification emails. The script should be run regularly - ideally every minute.';
$string['cron_link'] = 'admin/cron';
$string['cronclionly'] = 'Cron execution via command line only';
Expand Down
2 changes: 1 addition & 1 deletion lib/classes/task/manager.php
Expand Up @@ -1095,7 +1095,7 @@ public static function run_from_cli(\core\task\task_base $task):bool {

// Shell-escaped task name.
$classname = get_class($task);
$taskarg = escapeshellarg("--execute={$classname}");
$taskarg = escapeshellarg("--execute={$classname}") . " " . escapeshellarg("--force");

// Build the CLI command.
$command = "{$phpbinary} {$scriptpath} {$taskarg}";
Expand Down
10 changes: 10 additions & 0 deletions lib/outputlib.php
Expand Up @@ -270,6 +270,16 @@ function theme_reset_all_caches() {
}
}

/**
* Reset static caches.
*
* This method indicates that all running cron processes should exit at the
* next opportunity.
*/
function theme_reset_static_caches() {
\core\task\manager::clear_static_caches();
}

/**
* Enable or disable theme designer mode.
*
Expand Down

0 comments on commit d7342dc

Please sign in to comment.