Merge branch 'MDL-47529-master' of git://github.com/FMCorz/moodle

This commit is contained in:
David Monllao 2015-02-16 11:52:50 +08:00
commit 470e087d80
3 changed files with 45 additions and 48 deletions

View File

@ -507,7 +507,7 @@ $CFG->admin = 'admin';
// Uses lock files stored by default in the dataroot. Whether this
// works on clusters depends on the file system used for the dataroot.
//
// "\\core\\lock\\db_row_lock_factory" - DB locking based on table rows.
// "\\core\\lock\\db_record_lock_factory" - DB locking based on table rows.
//
// "\\core\\lock\\postgres_lock_factory" - DB locking based on postgres advisory locks.
//

View File

@ -85,53 +85,31 @@ class manager {
*/
public static function reset_scheduled_tasks_for_component($componentname) {
global $DB;
$cronlockfactory = \core\lock\lock_config::get_lock_factory('cron');
if (!$cronlock = $cronlockfactory->get_lock('core_cron', 10, 60)) {
throw new \moodle_exception('locktimeout');
}
$tasks = self::load_default_scheduled_tasks_for_component($componentname);
$tasklocks = array();
foreach ($tasks as $taskid => $task) {
$classname = get_class($task);
if (strpos($classname, '\\') !== 0) {
$classname = '\\' . $classname;
}
// For tasks, the first run should also follow the schedule.
$task->set_next_run_time($task->get_next_scheduled_time());
// If there is an existing task with a custom schedule, do not override it.
$currenttask = self::get_scheduled_task($classname);
if ($currenttask && $currenttask->is_customised()) {
$tasks[$taskid] = $currenttask;
}
if (!$lock = $cronlockfactory->get_lock($classname, 10, 60)) {
// Could not get all the locks required - release all locks and fail.
foreach ($tasklocks as $tasklock) {
$tasklock->release();
if ($currenttask = self::get_scheduled_task($classname)) {
if ($currenttask->is_customised()) {
// If there is an existing task with a custom schedule, do not override it.
continue;
}
$cronlock->release();
throw new \moodle_exception('locktimeout');
// Update the record from the default task data.
self::configure_scheduled_task($task);
} else {
// Ensure that the first run follows the schedule.
$task->set_next_run_time($task->get_next_scheduled_time());
// Insert the new task in the database.
$record = self::record_from_scheduled_task($task);
$DB->insert_record('task_scheduled', $record);
}
$tasklocks[] = $lock;
}
// Got a lock on cron and all the tasks for this component, time to reset the config.
$DB->delete_records('task_scheduled', array('component' => $componentname));
foreach ($tasks as $task) {
$record = self::record_from_scheduled_task($task);
$DB->insert_record('task_scheduled', $record);
}
// Release the locks.
foreach ($tasklocks as $tasklock) {
$tasklock->release();
}
$cronlock->release();
}
/**
@ -160,20 +138,11 @@ class manager {
*/
public static function configure_scheduled_task(scheduled_task $task) {
global $DB;
$cronlockfactory = \core\lock\lock_config::get_lock_factory('cron');
if (!$cronlock = $cronlockfactory->get_lock('core_cron', 10, 60)) {
throw new \moodle_exception('locktimeout');
}
$classname = get_class($task);
if (strpos($classname, '\\') !== 0) {
$classname = '\\' . $classname;
}
if (!$lock = $cronlockfactory->get_lock($classname, 10, 60)) {
$cronlock->release();
throw new \moodle_exception('locktimeout');
}
$original = $DB->get_record('task_scheduled', array('classname'=>$classname), 'id', MUST_EXIST);
@ -182,8 +151,6 @@ class manager {
$record->nextruntime = $task->get_next_scheduled_time();
$result = $DB->update_record('task_scheduled', $record);
$lock->release();
$cronlock->release();
return $result;
}

View File

@ -177,6 +177,25 @@ class core_scheduled_task_testcase extends advanced_testcase {
// We reset this field, because we do not want to compare it.
$firsttaskrecord->nextruntime = '0';
// Delete a task to simulate the fact that its new.
$secondtask = next($defaulttasks);
$DB->delete_records('task_scheduled', array('classname' => '\\' . trim(get_class($secondtask), '\\')));
$this->assertFalse(\core\task\manager::get_scheduled_task(get_class($secondtask)));
// Edit a task to simulate a change in its definition (as if it was not customised).
$thirdtask = next($defaulttasks);
$thirdtask->set_minute('1');
$thirdtask->set_hour('2');
$thirdtask->set_month('3');
$thirdtask->set_day_of_week('4');
$thirdtask->set_day('5');
$thirdtaskbefore = \core\task\manager::get_scheduled_task(get_class($thirdtask));
$thirdtaskbefore->set_next_run_time(null); // Ignore this value when comparing.
\core\task\manager::configure_scheduled_task($thirdtask);
$thirdtask = \core\task\manager::get_scheduled_task(get_class($thirdtask));
$thirdtask->set_next_run_time(null); // Ignore this value when comparing.
$this->assertNotEquals($thirdtaskbefore, $thirdtask);
// Now call reset on all the tasks.
\core\task\manager::reset_scheduled_tasks_for_component('moodle');
@ -192,6 +211,17 @@ class core_scheduled_task_testcase extends advanced_testcase {
// Assert a customised task was not altered by reset.
$this->assertEquals($firsttaskrecord, $newfirsttaskrecord);
// Assert that the second task was added back.
$secondtaskafter = \core\task\manager::get_scheduled_task(get_class($secondtask));
$secondtaskafter->set_next_run_time(null); // Do not compare the nextruntime.
$secondtask->set_next_run_time(null);
$this->assertEquals($secondtask, $secondtaskafter);
// Assert that the third task edits were overridden.
$thirdtaskafter = \core\task\manager::get_scheduled_task(get_class($thirdtask));
$thirdtaskafter->set_next_run_time(null);
$this->assertEquals($thirdtaskbefore, $thirdtaskafter);
// Assert we have the same number of tasks.
$this->assertEquals($initcount, $finalcount);
}