Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   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  namespace cachestore_redis\task;
  18  
  19  /**
  20   * Task deletes old data from Redis caches with TTL set.
  21   *
  22   * @package cachestore_redis
  23   * @copyright 2021 The Open University
  24   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  class ttl extends \core\task\scheduled_task {
  27      /** @var int Only display memory savings of at least 100 KB */
  28      const MIN_MEMORY_SIZE = 100 * 1024;
  29  
  30      /**
  31       * Gets the name of this task.
  32       *
  33       * @return string Task name
  34       */
  35      public function get_name(): string {
  36          return get_string('task_ttl', 'cachestore_redis');
  37      }
  38  
  39      /**
  40       * Executes the scheduled task.
  41       */
  42      public function execute(): void {
  43          // Find all Redis cache stores.
  44          $factory = \cache_factory::instance();
  45          $config = $factory->create_config_instance();
  46          $stores = $config->get_all_stores();
  47          $doneanything = false;
  48          foreach ($stores as $storename => $storeconfig) {
  49              if ($storeconfig['plugin'] !== 'redis') {
  50                  continue;
  51              }
  52  
  53              // For each definition in the cache store, do TTL expiry if needed.
  54              $definitions = $config->get_definitions_by_store($storename);
  55              foreach ($definitions as $definition) {
  56                  if (empty($definition['ttl'])) {
  57                      continue;
  58                  }
  59                  if (!empty($definition['requireidentifiers'])) {
  60                      // We can't make cache below if it requires identifiers.
  61                      continue;
  62                  }
  63                  $doneanything = true;
  64                  $definitionname = $definition['component'] . '/' . $definition['area'];
  65                  mtrace($definitionname, ': ');
  66                  \cache::make($definition['component'], $definition['area']);
  67                  $definition = $factory->create_definition($definition['component'], $definition['area']);
  68                  $stores = $factory->get_store_instances_in_use($definition);
  69                  foreach ($stores as $store) {
  70                      // These were all definitions using a Redis store but one definition may
  71                      // potentially have multiple stores, we need to process the Redis ones only.
  72                      if (!($store instanceof \cachestore_redis)) {
  73                          continue;
  74                      }
  75                      $info = $store->expire_ttl();
  76                      $infotext = 'Deleted ' . $info['keys'] . ' key(s) in ' .
  77                              sprintf('%0.2f', $info['time'])  . 's';
  78                      // Only report memory information if available, positive, and reasonably large.
  79                      // Otherwise the real information is hard to see amongst random variation etc.
  80                      if (!empty($info['memory']) && $info['memory'] > self::MIN_MEMORY_SIZE) {
  81                          $infotext .= ' - reported saving ' . display_size($info['memory']);
  82                      }
  83                      mtrace($infotext);
  84                  }
  85              }
  86          }
  87          if (!$doneanything) {
  88              mtrace('No TTL caches assigned to a Redis store; nothing to do.');
  89          }
  90      }
  91  
  92      /**
  93       * Checks if this task is allowed to run - this makes it show the 'Run now' link (or not).
  94       *
  95       * @return bool True if task can run
  96       */
  97      public function can_run(): bool {
  98          // The default implementation of this function checks the plugin is enabled, which doesn't
  99          // seem to work (probably because cachestore plugins can't be enabled).
 100          // We could check if there is a Redis store configured, but it would have to do the exact
 101          // same logic as already in the first part of 'execute', so it's probably OK to just return
 102          // true.
 103          return true;
 104      }
 105  }