1<?php 2/** 3 * Lock manager registration handling. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 * http://www.gnu.org/copyleft/gpl.html 19 * 20 * @file 21 * @ingroup LockManager 22 */ 23use MediaWiki\Logger\LoggerFactory; 24use MediaWiki\MediaWikiServices; 25use Wikimedia\Rdbms\LBFactory; 26 27/** 28 * Class to handle file lock manager registration 29 * 30 * @ingroup LockManager 31 * @since 1.19 32 */ 33class LockManagerGroup { 34 /** @var string domain (usually wiki ID) */ 35 protected $domain; 36 37 /** @var LBFactory */ 38 protected $lbFactory; 39 40 /** @var array Array of (name => ('class' => ..., 'config' => ..., 'instance' => ...)) */ 41 protected $managers = []; 42 43 /** 44 * Do not call this directly. Use LockManagerGroupFactory. 45 * 46 * @param string $domain Domain (usually wiki ID) 47 * @param array[] $lockManagerConfigs In format of $wgLockManagers 48 * @param LBFactory $lbFactory 49 */ 50 public function __construct( $domain, array $lockManagerConfigs, LBFactory $lbFactory ) { 51 $this->domain = $domain; 52 $this->lbFactory = $lbFactory; 53 54 foreach ( $lockManagerConfigs as $config ) { 55 $config['domain'] = $this->domain; 56 if ( !isset( $config['name'] ) ) { 57 throw new Exception( "Cannot register a lock manager with no name." ); 58 } 59 $name = $config['name']; 60 if ( !isset( $config['class'] ) ) { 61 throw new Exception( "Cannot register lock manager `{$name}` with no class." ); 62 } 63 $class = $config['class']; 64 unset( $config['class'] ); // lock manager won't need this 65 $this->managers[$name] = [ 66 'class' => $class, 67 'config' => $config, 68 'instance' => null 69 ]; 70 } 71 } 72 73 /** 74 * @deprecated since 1.34, use LockManagerGroupFactory 75 * 76 * @param bool|string $domain Domain (usually wiki ID). Default: false. 77 * @return LockManagerGroup 78 */ 79 public static function singleton( $domain = false ) { 80 return MediaWikiServices::getInstance()->getLockManagerGroupFactory() 81 ->getLockManagerGroup( $domain ); 82 } 83 84 /** 85 * Destroy the singleton instances 86 * 87 * @deprecated since 1.34, use resetServiceForTesting() on LockManagerGroupFactory 88 */ 89 public static function destroySingletons() { 90 MediaWikiServices::getInstance()->resetServiceForTesting( 'LockManagerGroupFactory' ); 91 } 92 93 /** 94 * Get the lock manager object with a given name 95 * 96 * @param string $name 97 * @return LockManager 98 * @throws Exception 99 */ 100 public function get( $name ) { 101 if ( !isset( $this->managers[$name] ) ) { 102 throw new Exception( "No lock manager defined with the name `$name`." ); 103 } 104 // Lazy-load the actual lock manager instance 105 if ( !isset( $this->managers[$name]['instance'] ) ) { 106 $class = $this->managers[$name]['class']; 107 '@phan-var string $class'; 108 $config = $this->managers[$name]['config']; 109 $config['logger'] = LoggerFactory::getInstance( 'LockManager' ); 110 111 $this->managers[$name]['instance'] = new $class( $config ); 112 } 113 114 return $this->managers[$name]['instance']; 115 } 116 117 /** 118 * Get the config array for a lock manager object with a given name 119 * 120 * @param string $name 121 * @return array 122 * @throws Exception 123 */ 124 public function config( $name ) { 125 if ( !isset( $this->managers[$name] ) ) { 126 throw new Exception( "No lock manager defined with the name `$name`." ); 127 } 128 $class = $this->managers[$name]['class']; 129 130 return [ 'class' => $class ] + $this->managers[$name]['config']; 131 } 132 133 /** 134 * Get the default lock manager configured for the site. 135 * Returns NullLockManager if no lock manager could be found. 136 * 137 * @codeCoverageIgnore 138 * @deprecated since 1.35, seemingly unused, just call get() and catch any exception instead 139 * @return LockManager 140 */ 141 public function getDefault() { 142 wfDeprecated( __METHOD__, '1.35' ); 143 144 return isset( $this->managers['default'] ) 145 ? $this->get( 'default' ) 146 : new NullLockManager( [] ); 147 } 148 149 /** 150 * Get the default lock manager configured for the site 151 * or at least some other effective configured lock manager. 152 * Throws an exception if no lock manager could be found. 153 * 154 * @codeCoverageIgnore 155 * @deprecated since 1.35, seemingly unused, just call get() and catch any exception instead 156 * @return LockManager 157 * @throws Exception 158 */ 159 public function getAny() { 160 wfDeprecated( __METHOD__, '1.35' ); 161 162 return isset( $this->managers['default'] ) 163 ? $this->get( 'default' ) 164 : $this->get( 'fsLockManager' ); 165 } 166} 167