Differences Between: [Versions 401 and 403] [Versions 402 and 403]
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 core\lock; 18 19 use coding_exception; 20 21 /** 22 * Timing wrapper around a lock factory. 23 * 24 * This passes all calls through to the underlying lock factory, but adds timing information on how 25 * long it takes to get a lock and how long the lock is held for. 26 * 27 * @package core 28 * @category lock 29 * @copyright 2022 The Open University 30 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 31 */ 32 class timing_wrapper_lock_factory implements lock_factory { 33 34 /** @var lock_factory Real lock factory */ 35 protected $factory; 36 37 /** @var string Type (Frankenstyle) used for these locks */ 38 protected $type; 39 40 /** 41 * Constructor required by interface. 42 * 43 * @param string $type Type (should be same as passed to real lock factory) 44 * @param lock_factory $factory Real lock factory 45 */ 46 public function __construct($type, lock_factory $factory = null) { 47 $this->type = $type; 48 if (!$factory) { 49 // This parameter has to be optional because of the interface, but it is actually 50 // required. 51 throw new \coding_exception('The $factory parameter must be specified'); 52 } 53 $this->factory = $factory; 54 } 55 56 /** 57 * Gets the real lock factory that this is wrapping. 58 * 59 * @return lock_factory ReaL lock factory 60 */ 61 public function get_real_factory(): lock_factory { 62 return $this->factory; 63 } 64 65 /** 66 * Implementation of lock_factory::get_lock that defers to function inner_get_lock and keeps 67 * track of how long it took. 68 * 69 * @param string $resource Identifier for the lock 70 * @param int $timeout Number of seconds to wait for a lock before giving up 71 * @param int $maxlifetime Number of seconds to wait before reclaiming a stale lock 72 * @return \core\lock\lock|boolean - An instance of \core\lock\lock if the lock was obtained, or false. 73 */ 74 public function get_lock($resource, $timeout, $maxlifetime = 86400) { 75 $before = microtime(true); 76 77 $result = $this->factory->get_lock($resource, $timeout, $maxlifetime); 78 79 $after = microtime(true); 80 self::record_lock_data($after, $before, $this->type, $resource, (bool)$result, $result); 81 if ($result) { 82 $result->init_factory($this); 83 } 84 85 return $result; 86 } 87 88 /** 89 * Records statistics about a lock to the performance data. 90 * 91 * @param float $after The time after the lock was achieved. 92 * @param float $before The time before the lock was requested. 93 * @param string $type The type of lock. 94 * @param string $resource The resource being locked. 95 * @param bool $result Whether the lock was successful. 96 * @param lock|string $lock A value uniquely identifying the lock. 97 * @return void 98 */ 99 public static function record_lock_data(float $after, float $before, string $type, string $resource, bool $result, $lock) { 100 global $PERF; 101 $duration = $after - $before; 102 if (empty($PERF->locks)) { 103 $PERF->locks = []; 104 } 105 $lockdata = (object) [ 106 'type' => $type, 107 'resource' => $resource, 108 'wait' => $duration, 109 'success' => $result 110 ]; 111 if ($result) { 112 $lockdata->lock = $lock; 113 $lockdata->timestart = $after; 114 } 115 $PERF->locks[] = $lockdata; 116 } 117 118 /** 119 * Release a lock that was previously obtained with {@see get_lock}. 120 * 121 * @param lock $lock - The lock to release. 122 * @return boolean - True if the lock is no longer held (including if it was never held). 123 */ 124 public function release_lock(lock $lock) { 125 self::record_lock_released_data($lock); 126 return $this->factory->release_lock($lock); 127 } 128 129 /** 130 * Find the lock in the performance info and update it with the time held. 131 * 132 * @param lock|string $lock A value uniquely identifying the lock. 133 * @return void 134 */ 135 public static function record_lock_released_data($lock) { 136 global $PERF; 137 138 // Find this lock in the list of locks we got, looking backwards since it is probably 139 // the last one. 140 for ($index = count($PERF->locks) - 1; $index >= 0; $index--) { 141 $lockdata = $PERF->locks[$index]; 142 if (!empty($lockdata->lock) && $lockdata->lock === $lock) { 143 // Update the time held. 144 unset($lockdata->lock); 145 $lockdata->held = microtime(true) - $lockdata->timestart; 146 break; 147 } 148 } 149 } 150 151 /** 152 * Calls parent factory to check if it supports timeout. 153 * 154 * @return boolean False if attempting to get a lock will block indefinitely. 155 */ 156 public function supports_timeout() { 157 return $this->factory->supports_timeout(); 158 } 159 160 /** 161 * Calls parent factory to check if it auto-releases locks. 162 * 163 * @return boolean True if this lock type will be automatically released when the current process ends. 164 */ 165 public function supports_auto_release() { 166 return $this->factory->supports_auto_release(); 167 } 168 169 /** 170 * @deprecated since Moodle 3.10. 171 */ 172 public function supports_recursion() { 173 throw new coding_exception('The function supports_recursion() has been removed, please do not use it anymore.'); 174 } 175 176 /** 177 * Calls parent factory to check if it is available. 178 * 179 * @return boolean True if this lock type is available in this environment. 180 */ 181 public function is_available() { 182 return $this->factory->is_available(); 183 } 184 185 /** 186 * @deprecated since Moodle 3.10. 187 */ 188 public function extend_lock() { 189 throw new coding_exception('The function extend_lock() has been removed, please do not use it anymore.'); 190 } 191 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body