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.
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

namespace core\lock;

> use coding_exception; /** >
* Timing wrapper around a lock factory. * * This passes all calls through to the underlying lock factory, but adds timing information on how * long it takes to get a lock and how long the lock is held for. * * @package core * @category lock * @copyright 2022 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ class timing_wrapper_lock_factory implements lock_factory { /** @var lock_factory Real lock factory */ protected $factory; /** @var string Type (Frankenstyle) used for these locks */ protected $type; /** * Constructor required by interface. * * @param string $type Type (should be same as passed to real lock factory) * @param lock_factory $factory Real lock factory */ public function __construct($type, lock_factory $factory = null) { $this->type = $type; if (!$factory) { // This parameter has to be optional because of the interface, but it is actually // required. throw new \coding_exception('The $factory parameter must be specified'); } $this->factory = $factory; } /** * Gets the real lock factory that this is wrapping. * * @return lock_factory ReaL lock factory */ public function get_real_factory(): lock_factory { return $this->factory; } /** * Implementation of lock_factory::get_lock that defers to function inner_get_lock and keeps * track of how long it took. * * @param string $resource Identifier for the lock * @param int $timeout Number of seconds to wait for a lock before giving up * @param int $maxlifetime Number of seconds to wait before reclaiming a stale lock * @return \core\lock\lock|boolean - An instance of \core\lock\lock if the lock was obtained, or false. */ public function get_lock($resource, $timeout, $maxlifetime = 86400) { $before = microtime(true); $result = $this->factory->get_lock($resource, $timeout, $maxlifetime); $after = microtime(true); self::record_lock_data($after, $before, $this->type, $resource, (bool)$result, $result); if ($result) { $result->init_factory($this); } return $result; } /** * Records statistics about a lock to the performance data. * * @param float $after The time after the lock was achieved. * @param float $before The time before the lock was requested. * @param string $type The type of lock. * @param string $resource The resource being locked. * @param bool $result Whether the lock was successful. * @param lock|string $lock A value uniquely identifying the lock. * @return void */ public static function record_lock_data(float $after, float $before, string $type, string $resource, bool $result, $lock) { global $PERF; $duration = $after - $before; if (empty($PERF->locks)) { $PERF->locks = []; } $lockdata = (object) [ 'type' => $type, 'resource' => $resource, 'wait' => $duration, 'success' => $result ]; if ($result) { $lockdata->lock = $lock; $lockdata->timestart = $after; } $PERF->locks[] = $lockdata; } /** * Release a lock that was previously obtained with {@see get_lock}. * * @param lock $lock - The lock to release. * @return boolean - True if the lock is no longer held (including if it was never held). */ public function release_lock(lock $lock) { self::record_lock_released_data($lock); return $this->factory->release_lock($lock); } /** * Find the lock in the performance info and update it with the time held. * * @param lock|string $lock A value uniquely identifying the lock. * @return void */ public static function record_lock_released_data($lock) { global $PERF; // Find this lock in the list of locks we got, looking backwards since it is probably // the last one. for ($index = count($PERF->locks) - 1; $index >= 0; $index--) { $lockdata = $PERF->locks[$index]; if (!empty($lockdata->lock) && $lockdata->lock === $lock) { // Update the time held. unset($lockdata->lock); $lockdata->held = microtime(true) - $lockdata->timestart; break; } } } /** * Calls parent factory to check if it supports timeout. * * @return boolean False if attempting to get a lock will block indefinitely. */ public function supports_timeout() { return $this->factory->supports_timeout(); } /** * Calls parent factory to check if it auto-releases locks. * * @return boolean True if this lock type will be automatically released when the current process ends. */ public function supports_auto_release() { return $this->factory->supports_auto_release(); } /**
< * Calls parent factory to check if it supports recursion. < *
* @deprecated since Moodle 3.10.
< * @return boolean True if attempting to get 2 locks on the same resource will "stack"
*/ public function supports_recursion() {
< return $this->factory->supports_recursion();
> throw new coding_exception('The function supports_recursion() has been removed, please do not use it anymore.');
} /** * Calls parent factory to check if it is available. * * @return boolean True if this lock type is available in this environment. */ public function is_available() { return $this->factory->is_available(); } /**
< * Calls parent factory to try to extend the lock. < *
* @deprecated since Moodle 3.10.
< * @param lock $lock Lock obtained from this factory < * @param int $maxlifetime New max time to hold the lock < * @return boolean True if the lock was extended.
*/
< public function extend_lock(lock $lock, $maxlifetime = 86400) { < return $this->factory->extend_lock($lock, $maxlifetime);
> public function extend_lock() { > throw new coding_exception('The function extend_lock() has been removed, please do not use it anymore.');
} }