From 516ea6cf8b5650ac086630b3f4c609a09a685040 Mon Sep 17 00:00:00 2001 From: Dan Poltawski Date: Sat, 27 Sep 2014 21:22:57 +0100 Subject: [PATCH] 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. --- lib/classes/task/scheduled_task.php | 25 +++++++++++++++++++---- lib/tests/scheduled_task_test.php | 31 +++++++++++++++++++++++++++++ lib/upgrade.txt | 3 +++ 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/lib/classes/task/scheduled_task.php b/lib/classes/task/scheduled_task.php index ed2fc03144c..9c525e5860d 100644 --- a/lib/classes/task/scheduled_task.php +++ b/lib/classes/task/scheduled_task.php @@ -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(); diff --git a/lib/tests/scheduled_task_test.php b/lib/tests/scheduled_task_test.php index bb81535d0a4..599c5010082 100644 --- a/lib/tests/scheduled_task_test.php +++ b/lib/tests/scheduled_task_test.php @@ -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); + } } diff --git a/lib/upgrade.txt b/lib/upgrade.txt index acf6e019cdc..339eebe13f6 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -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. -- 2.43.0