]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - includes/filebackend/lockmanager/LockManagerGroup.php
MediaWiki 1.30.2
[autoinstalls/mediawiki.git] / includes / filebackend / lockmanager / LockManagerGroup.php
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  */
23 use MediaWiki\MediaWikiServices;
24 use MediaWiki\Logger\LoggerFactory;
25
26 /**
27  * Class to handle file lock manager registration
28  *
29  * @ingroup LockManager
30  * @since 1.19
31  */
32 class LockManagerGroup {
33         /** @var LockManagerGroup[] (domain => LockManagerGroup) */
34         protected static $instances = [];
35
36         protected $domain; // string; domain (usually wiki ID)
37
38         /** @var array Array of (name => ('class' => ..., 'config' => ..., 'instance' => ...)) */
39         protected $managers = [];
40
41         /**
42          * @param string $domain Domain (usually wiki ID)
43          */
44         protected function __construct( $domain ) {
45                 $this->domain = $domain;
46         }
47
48         /**
49          * @param bool|string $domain Domain (usually wiki ID). Default: false.
50          * @return LockManagerGroup
51          */
52         public static function singleton( $domain = false ) {
53                 $domain = ( $domain === false ) ? wfWikiID() : $domain;
54                 if ( !isset( self::$instances[$domain] ) ) {
55                         self::$instances[$domain] = new self( $domain );
56                         self::$instances[$domain]->initFromGlobals();
57                 }
58
59                 return self::$instances[$domain];
60         }
61
62         /**
63          * Destroy the singleton instances
64          */
65         public static function destroySingletons() {
66                 self::$instances = [];
67         }
68
69         /**
70          * Register lock managers from the global variables
71          */
72         protected function initFromGlobals() {
73                 global $wgLockManagers;
74
75                 $this->register( $wgLockManagers );
76         }
77
78         /**
79          * Register an array of file lock manager configurations
80          *
81          * @param array $configs
82          * @throws Exception
83          */
84         protected function register( array $configs ) {
85                 foreach ( $configs as $config ) {
86                         $config['domain'] = $this->domain;
87                         if ( !isset( $config['name'] ) ) {
88                                 throw new Exception( "Cannot register a lock manager with no name." );
89                         }
90                         $name = $config['name'];
91                         if ( !isset( $config['class'] ) ) {
92                                 throw new Exception( "Cannot register lock manager `{$name}` with no class." );
93                         }
94                         $class = $config['class'];
95                         unset( $config['class'] ); // lock manager won't need this
96                         $this->managers[$name] = [
97                                 'class' => $class,
98                                 'config' => $config,
99                                 'instance' => null
100                         ];
101                 }
102         }
103
104         /**
105          * Get the lock manager object with a given name
106          *
107          * @param string $name
108          * @return LockManager
109          * @throws Exception
110          */
111         public function get( $name ) {
112                 if ( !isset( $this->managers[$name] ) ) {
113                         throw new Exception( "No lock manager defined with the name `$name`." );
114                 }
115                 // Lazy-load the actual lock manager instance
116                 if ( !isset( $this->managers[$name]['instance'] ) ) {
117                         $class = $this->managers[$name]['class'];
118                         $config = $this->managers[$name]['config'];
119                         if ( $class === 'DBLockManager' ) {
120                                 $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
121                                 $lb = $lbFactory->newMainLB( $config['domain'] );
122                                 $dbw = $lb->getLazyConnectionRef( DB_MASTER, [], $config['domain'] );
123
124                                 $config['dbServers']['localDBMaster'] = $dbw;
125                                 $config['srvCache'] = ObjectCache::getLocalServerInstance( 'hash' );
126                         }
127                         $config['logger'] = LoggerFactory::getInstance( 'LockManager' );
128
129                         $this->managers[$name]['instance'] = new $class( $config );
130                 }
131
132                 return $this->managers[$name]['instance'];
133         }
134
135         /**
136          * Get the config array for a lock manager object with a given name
137          *
138          * @param string $name
139          * @return array
140          * @throws Exception
141          */
142         public function config( $name ) {
143                 if ( !isset( $this->managers[$name] ) ) {
144                         throw new Exception( "No lock manager defined with the name `$name`." );
145                 }
146                 $class = $this->managers[$name]['class'];
147
148                 return [ 'class' => $class ] + $this->managers[$name]['config'];
149         }
150
151         /**
152          * Get the default lock manager configured for the site.
153          * Returns NullLockManager if no lock manager could be found.
154          *
155          * @return LockManager
156          */
157         public function getDefault() {
158                 return isset( $this->managers['default'] )
159                         ? $this->get( 'default' )
160                         : new NullLockManager( [] );
161         }
162
163         /**
164          * Get the default lock manager configured for the site
165          * or at least some other effective configured lock manager.
166          * Throws an exception if no lock manager could be found.
167          *
168          * @return LockManager
169          * @throws Exception
170          */
171         public function getAny() {
172                 return isset( $this->managers['default'] )
173                         ? $this->get( 'default' )
174                         : $this->get( 'fsLockManager' );
175         }
176 }