MDL-47221 task: allow 'random' time definitions

When working against external services it can be advantageous to not
have automated tasks all hit the service at the exact same time from
many different installations.

This change allows the use of 'R' in hour/minute fields of the scheduled
task definition so a task will be installed with a 'random' hour/minute
value for these sort of occasions.

Note that the task will be installed in the database with a defined
time, this simply randomises the time chosen when loading from the
definiton.
This commit is contained in:
Dan Poltawski
2014-10-05 14:27:04 +01:00
parent 6597413d41
commit 16078807f8
3 changed files with 55 additions and 4 deletions
+21 -4
View File
@@ -31,6 +31,15 @@ namespace core\task;
*/
abstract class scheduled_task extends task_base {
/** Minimum minute value. */
const MINUTEMIN = 0;
/** Maximum minute value. */
const MINUTEMAX = 59;
/** Minimum hour value. */
const HOURMIN = 0;
/** Maximum hour value. */
const HOURMAX = 23;
/** @var string $hour - Pattern to work out the valid hours */
private $hour = '*';
@@ -88,10 +97,14 @@ abstract class scheduled_task extends task_base {
}
/**
* Setter for $minute.
* Setter for $minute. Accepts a special 'R' value
* which will be translated to a random minute.
* @param string $minute
*/
public function set_minute($minute) {
if ($minute === 'R') {
$minute = mt_rand(self::HOURMIN, self::HOURMAX);
}
$this->minute = $minute;
}
@@ -104,10 +117,14 @@ abstract class scheduled_task extends task_base {
}
/**
* Setter for $hour.
* Setter for $hour. Accepts a special 'R' value
* which will be translated to a random hour.
* @param string $hour
*/
public function set_hour($hour) {
if ($hour === 'R') {
$hour = mt_rand(self::HOURMIN, self::HOURMAX);
}
$this->hour = $hour;
}
@@ -302,8 +319,8 @@ abstract class scheduled_task extends task_base {
public function get_next_scheduled_time() {
global $CFG;
$validminutes = $this->eval_cron_field($this->minute, 0, 59);
$validhours = $this->eval_cron_field($this->hour, 0, 23);
$validminutes = $this->eval_cron_field($this->minute, self::MINUTEMIN, self::MINUTEMAX);
$validhours = $this->eval_cron_field($this->hour, self::HOURMIN, self::HOURMAX);
// We need to change to the server timezone before using php date() functions.
$origtz = date_default_timezone_get();
+31
View File
@@ -242,4 +242,35 @@ class core_scheduled_task_testcase extends advanced_testcase {
$this->assertDebuggingCalled();
$this->assertNull($task);
}
/**
* Tests the use of 'R' syntax in time fields of tasks to get
* tasks be configured with a non-uniform time.
*/
public function test_random_time_specification() {
// Testing non-deterministic things in a unit test is not really
// wise, so we just test the values have changed within allowed bounds.
$testclass = new \core\task\scheduled_test_task();
// The test task defaults to '*'.
$this->assertInternalType('string', $testclass->get_minute());
$this->assertInternalType('string', $testclass->get_hour());
// Set a random value.
$testclass->set_minute('R');
$testclass->set_hour('R');
// Verify the minute has changed within allowed bounds.
$minute = $testclass->get_minute();
$this->assertInternalType('int', $minute);
$this->assertGreaterThanOrEqual(0, $minute);
$this->assertLessThanOrEqual(59, $minute);
// Verify the hour has changed within allowed bounds.
$hour = $testclass->get_hour();
$this->assertInternalType('int', $hour);
$this->assertGreaterThanOrEqual(0, $hour);
$this->assertLessThanOrEqual(23, $hour);
}
}
+3
View File
@@ -13,6 +13,9 @@ information provided here is intended especially for developers.
* New function cm_info::create($cm) can be used when you need a cm_info
object, but have a $cm which might only be a standard database record.
* $CFG->enablegroupmembersonly no longer exists.
* Scheduled tasks have gained support for syntax to introduce variability when a
task will run across installs. When a when hour or minute are defined as 'R'
they will be installed with a random hour/minute value.
DEPRECATIONS:
* completion_info->get_incomplete_criteria() is deprecated and will be removed in Moodle 3.0.