Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.

Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Abstract class for common properties of scheduled_task and adhoc_task.
  19   *
  20   * @package    core
  21   * @category   task
  22   * @copyright  2013 Damyon Wiese
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  namespace core\task;
  26  
  27  use core_component;
  28  use core_plugin_manager;
  29  use core\check\result;
  30  
  31  /**
  32   * Abstract class for common properties of scheduled_task and adhoc_task.
  33   *
  34   * @copyright  2013 Damyon Wiese
  35   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  abstract class task_base {
  38  
  39      /** @var \core\lock\lock $lock - The lock controlling this task. */
  40      private $lock = null;
  41  
  42      /** @var \core\lock\lock $cronlock - The lock controlling the entire cron process. */
  43      private $cronlock = null;
  44  
  45      /** @var string $component - The component this task belongs to. */
  46      private $component = '';
  47  
  48      /** @var bool $blocking - Does this task block the entire cron process. */
  49      private $blocking = false;
  50  
  51      /** @var int $faildelay - Exponentially increasing fail delay */
  52      private $faildelay = 0;
  53  
  54      /** @var int $nextruntime - When this task is due to run next */
  55      private $nextruntime = 0;
  56  
  57      /** @var int $timestarted - When this task was started */
  58      private $timestarted = null;
  59  
  60      /** @var string $hostname - Hostname where this task was started and PHP process ID */
  61      private $hostname = null;
  62  
  63      /** @var int $pid - PHP process ID that is running the task */
  64      private $pid = null;
  65  
  66      /**
  67       * Get a descriptive name for the task (shown to admins)
  68       *
  69       * @return string
  70       */
  71      abstract public function get_name();
  72  
  73      /**
  74       * Set the current lock for this task.
  75       * @param \core\lock\lock $lock
  76       */
  77      public function set_lock(\core\lock\lock $lock) {
  78          $this->lock = $lock;
  79      }
  80  
  81      /**
  82       * Set the current lock for the entire cron process.
  83       * @param \core\lock\lock $lock
  84       */
  85      public function set_cron_lock(\core\lock\lock $lock) {
  86          $this->cronlock = $lock;
  87      }
  88  
  89      /**
  90       * Get the current lock for this task.
  91       * @return \core\lock\lock
  92       */
  93      public function get_lock() {
  94          return $this->lock;
  95      }
  96  
  97      /**
  98       * Get the next run time for this task.
  99       * @return int timestamp
 100       */
 101      public function get_next_run_time() {
 102          return $this->nextruntime;
 103      }
 104  
 105      /**
 106       * Set the next run time for this task.
 107       * @param int $nextruntime
 108       */
 109      public function set_next_run_time($nextruntime) {
 110          $this->nextruntime = $nextruntime;
 111      }
 112  
 113      /**
 114       * Get the current lock for the entire cron.
 115       * @return \core\lock\lock
 116       */
 117      public function get_cron_lock() {
 118          return $this->cronlock;
 119      }
 120  
 121      /**
 122       * Setter for $blocking.
 123       * @param bool $blocking
 124       */
 125      public function set_blocking($blocking) {
 126          $this->blocking = $blocking;
 127      }
 128  
 129      /**
 130       * Getter for $blocking.
 131       * @return bool
 132       */
 133      public function is_blocking() {
 134          return $this->blocking;
 135      }
 136  
 137      /**
 138       * Setter for $component.
 139       * @param string $component
 140       */
 141      public function set_component($component) {
 142          $this->component = $component;
 143      }
 144  
 145      /**
 146       * Getter for $component.
 147       * @return string
 148       */
 149      public function get_component() {
 150          if (empty($this->component)) {
 151              // The component should be the root of the class namespace.
 152              $classname = get_class($this);
 153              $parts = explode('\\', $classname);
 154  
 155              if (count($parts) === 1) {
 156                  $component = substr($classname, 0, strpos($classname, '_task'));
 157              } else {
 158                  [$component] = $parts;
 159              }
 160  
 161              // Load component information from plugin manager.
 162              if ($component !== 'core' && strpos($component, 'core_') !== 0) {
 163                  $plugininfo = \core_plugin_manager::instance()->get_plugin_info($component);
 164                  if ($plugininfo && $plugininfo->component) {
 165                      $this->set_component($plugininfo->component);
 166                  } else {
 167                      debugging("Component not set and the class namespace does not match a valid component ({$component}).");
 168                  }
 169              }
 170          }
 171  
 172          return $this->component;
 173      }
 174  
 175      /**
 176       * Setter for $faildelay.
 177       * @param int $faildelay
 178       */
 179      public function set_fail_delay($faildelay) {
 180          $this->faildelay = $faildelay;
 181      }
 182  
 183      /**
 184       * Getter for $faildelay.
 185       * @return int
 186       */
 187      public function get_fail_delay() {
 188          return $this->faildelay;
 189      }
 190  
 191      /**
 192       * Do the job.
 193       * Throw exceptions on errors (the job will be retried).
 194       */
 195      public abstract function execute();
 196  
 197      /**
 198       * Setter for $timestarted.
 199       * @param int $timestarted
 200       */
 201      public function set_timestarted($timestarted = null) {
 202          $this->timestarted = $timestarted;
 203      }
 204  
 205      /**
 206       * Getter for $timestarted.
 207       * @return int
 208       */
 209      public function get_timestarted() {
 210          return $this->timestarted;
 211      }
 212  
 213      /**
 214       * Setter for $hostname.
 215       * @param string $hostname
 216       */
 217      public function set_hostname($hostname = null) {
 218          $this->hostname = $hostname;
 219      }
 220  
 221      /**
 222       * Getter for $hostname.
 223       * @return string
 224       */
 225      public function get_hostname() {
 226          return $this->hostname;
 227      }
 228  
 229      /**
 230       * Setter for $pid.
 231       * @param int $pid
 232       */
 233      public function set_pid($pid = null) {
 234          $this->pid = $pid;
 235      }
 236  
 237      /**
 238       * Getter for $pid.
 239       * @return int
 240       */
 241      public function get_pid() {
 242          return $this->pid;
 243      }
 244  
 245      /**
 246       * Informs whether the task's component is enabled.
 247       * @return bool true when enabled. false otherwise.
 248       */
 249      public function is_component_enabled(): bool {
 250          $component = $this->get_component();
 251  
 252          // An entire core component type cannot be explicitly disabled.
 253          [$componenttype] = core_component::normalize_component($component);
 254          if ($componenttype === 'core') {
 255              return true;
 256          } else {
 257              $plugininfo = core_plugin_manager::instance()->get_plugin_info($component);
 258              return $plugininfo && ($plugininfo->is_enabled() !== false);
 259          }
 260      }
 261  
 262      /**
 263       * Returns task runtime
 264       * @return int
 265       */
 266      public function get_runtime() {
 267          return time() - $this->timestarted;
 268      }
 269  
 270      /**
 271       * Returns if the task has been running for too long
 272       * @return result
 273       */
 274      public function get_runtime_result() {
 275          global $CFG;
 276          $runtime = $this->get_runtime();
 277          $runtimeerror = $CFG->taskruntimeerror;
 278          $runtimewarn = $CFG->taskruntimewarn;
 279  
 280          $status = result::OK;
 281          $details = '';
 282  
 283          if ($runtime > $runtimewarn) {
 284              $status = result::WARNING;
 285              $details = get_string('slowtask', 'tool_task', format_time($runtimewarn));
 286          }
 287  
 288          if ($runtime > $runtimeerror) {
 289              $status = result::ERROR;
 290              $details = get_string('slowtask', 'tool_task', format_time($runtimeerror));
 291          }
 292  
 293          // This result is aggregated with other running tasks checks before display.
 294          return new result($status, '', $details);
 295      }
 296  
 297  }