Development talk:Scheduled Tasks Proposal
From MoodleDocs
Pseudo code proposal
This is just a rough idea to provoke thought:--Tim Hunt 11:06, 9 December 2009 (UTC)
<?php
function handle_cron($maxprocesstime) {
$timestart = time();
$runid = cron_record_starting_processing($timenow);
while (($timenow = time()) < $timestart + $maxprocesstime) {
try {
$task = cron_get_next_task($timenow);
cron_acquire_lock($task);
$next = $task->execute($timenow);
cron_record_task_success($task, $next, $timenow);
cron_release_lock($task);
} catch (Exception $e) {
cron_record_task_failure($task, $timenow, $e);
}
}
cron_record_ending_processing($runid, $timenow);
}
/**
* Instances of this class are rows in the scheduled_tasks table.
*/
abstract class scheduled_task {
protected $id;
protected $plugin; // = 'mod_quiz', 'qtype_multichoice'.
protected $function;
protected $lastruntime;
protected $nextscheduledtime;
protected $priority; // LOW, MEDIUM, HIGH, or, a number like nice 19, or something.
protected abstract function get_start_end_times($timenow);
protected abstract function schedule_next($timenow);
public function execute($timenow) {
$file = get_plugin_dir($this->plugin) . '/cron.php';
if (!is_readable($file)) {
throw new cron_exception('required file does not exist.');
}
if (include_once($file)) {
throw new cron_exception('required file could not be included.');
}
list($start, $end) = next_times($timenow);
$this->$function($start, $end);
return $this->schedule_next();
}
}
class one_off_task extends scheduled_task {
protected abstract function get_start_end_times($timenow) {
return array(null, $timenow);
}
protected abstract function schedule_next($timenow) {
return null;
}
}
class catchup_task extends scheduled_task {
protected $desiredinterval; // seconds
protected abstract function get_start_end_times($timenow) {
return array($lastruntime, $timenow);
}
protected abstract function schedule_next($timenow) {
return $timenow + $desiredinterval;
}
}
class every_day_task extends scheduled_task {
protected $swtichovertime; // Seconds after midnight.
protected $runtime; // Seconds after midnight.
// For now this code assumes $runtime > $swtichovertime, but that is just me
// being lazy. It can be fixed.
protected abstract function get_start_end_times($timenow) {
$midnight = get_midnight_before($this->nextscheduledtime);
$previousmidnight = get_previous_midnight($midnight);
$starttime = $previousmidnight + $swtichovertime;
$endtime = $midnight + $swtichovertime;
return array($starttime, $endtime);
}
protected abstract function schedule_next($timenow) {
$midnight = get_midnight_before($this->nextscheduledtime);
$nextmidnight = get_following_midnight($midnight);
return $nextmidnight + $this->runtime;
}
}
class weekly_task extends scheduled_task {
// ...
}
/* Approximate database tables.
scheduled_tasks
id AUTOINCREMENT
type varchar
plugin varchar
function varchar UNIQUE
lastruntime int
nextscheduledtime int
priority int
custom1 int
custom2 int
customextra text
scheduled_task_locks
id int auto
function fk unique
locktime int
- /