MediaWiki  REL1_22
LBFactory.php
Go to the documentation of this file.
00001 <?php
00028 abstract class LBFactory {
00029 
00033     static $instance;
00034 
00039     public static function disableBackend() {
00040         global $wgLBFactoryConf;
00041         self::$instance = new LBFactory_Fake( $wgLBFactoryConf );
00042     }
00043 
00049     static function &singleton() {
00050         if ( is_null( self::$instance ) ) {
00051             global $wgLBFactoryConf;
00052             $class = $wgLBFactoryConf['class'];
00053             self::$instance = new $class( $wgLBFactoryConf );
00054         }
00055         return self::$instance;
00056     }
00057 
00061     static function destroyInstance() {
00062         if ( self::$instance ) {
00063             self::$instance->shutdown();
00064             self::$instance->forEachLBCallMethod( 'closeAll' );
00065             self::$instance = null;
00066         }
00067     }
00068 
00074     static function setInstance( $instance ) {
00075         self::destroyInstance();
00076         self::$instance = $instance;
00077     }
00078 
00083     abstract function __construct( $conf );
00084 
00092     abstract function newMainLB( $wiki = false );
00093 
00100     abstract function getMainLB( $wiki = false );
00101 
00112     abstract function newExternalLB( $cluster, $wiki = false );
00113 
00122     abstract function &getExternalLB( $cluster, $wiki = false );
00123 
00131     abstract function forEachLB( $callback, $params = array() );
00132 
00137     function shutdown() {
00138     }
00139 
00145     function forEachLBCallMethod( $methodName, $args = array() ) {
00146         $this->forEachLB( array( $this, 'callMethod' ), array( $methodName, $args ) );
00147     }
00148 
00155     function callMethod( $loadBalancer, $methodName, $args ) {
00156         call_user_func_array( array( $loadBalancer, $methodName ), $args );
00157     }
00158 
00162     function commitMasterChanges() {
00163         $this->forEachLBCallMethod( 'commitMasterChanges' );
00164     }
00165 }
00166 
00170 class LBFactory_Simple extends LBFactory {
00171 
00175     var $mainLB;
00176     var $extLBs = array();
00177 
00178     # Chronology protector
00179     var $chronProt;
00180 
00181     function __construct( $conf ) {
00182         $this->chronProt = new ChronologyProtector;
00183     }
00184 
00189     function newMainLB( $wiki = false ) {
00190         global $wgDBservers, $wgMasterWaitTimeout;
00191         if ( $wgDBservers ) {
00192             $servers = $wgDBservers;
00193         } else {
00194             global $wgDBserver, $wgDBuser, $wgDBpassword, $wgDBname, $wgDBtype, $wgDebugDumpSql;
00195             global $wgDBssl, $wgDBcompress;
00196 
00197             $flags = ( $wgDebugDumpSql ? DBO_DEBUG : 0 ) | DBO_DEFAULT;
00198             if ( $wgDBssl ) {
00199                 $flags |= DBO_SSL;
00200             }
00201             if ( $wgDBcompress ) {
00202                 $flags |= DBO_COMPRESS;
00203             }
00204 
00205             $servers = array( array(
00206                 'host' => $wgDBserver,
00207                 'user' => $wgDBuser,
00208                 'password' => $wgDBpassword,
00209                 'dbname' => $wgDBname,
00210                 'type' => $wgDBtype,
00211                 'load' => 1,
00212                 'flags' => $flags
00213             ));
00214         }
00215 
00216         return new LoadBalancer( array(
00217             'servers' => $servers,
00218             'masterWaitTimeout' => $wgMasterWaitTimeout
00219         ));
00220     }
00221 
00226     function getMainLB( $wiki = false ) {
00227         if ( !isset( $this->mainLB ) ) {
00228             $this->mainLB = $this->newMainLB( $wiki );
00229             $this->mainLB->parentInfo( array( 'id' => 'main' ) );
00230             $this->chronProt->initLB( $this->mainLB );
00231         }
00232         return $this->mainLB;
00233     }
00234 
00241     function newExternalLB( $cluster, $wiki = false ) {
00242         global $wgExternalServers;
00243         if ( !isset( $wgExternalServers[$cluster] ) ) {
00244             throw new MWException( __METHOD__ . ": Unknown cluster \"$cluster\"" );
00245         }
00246         return new LoadBalancer( array(
00247             'servers' => $wgExternalServers[$cluster]
00248         ));
00249     }
00250 
00256     function &getExternalLB( $cluster, $wiki = false ) {
00257         if ( !isset( $this->extLBs[$cluster] ) ) {
00258             $this->extLBs[$cluster] = $this->newExternalLB( $cluster, $wiki );
00259             $this->extLBs[$cluster]->parentInfo( array( 'id' => "ext-$cluster" ) );
00260             $this->chronProt->initLB( $this->extLBs[$cluster] );
00261         }
00262         return $this->extLBs[$cluster];
00263     }
00264 
00272     function forEachLB( $callback, $params = array() ) {
00273         if ( isset( $this->mainLB ) ) {
00274             call_user_func_array( $callback, array_merge( array( $this->mainLB ), $params ) );
00275         }
00276         foreach ( $this->extLBs as $lb ) {
00277             call_user_func_array( $callback, array_merge( array( $lb ), $params ) );
00278         }
00279     }
00280 
00281     function shutdown() {
00282         if ( $this->mainLB ) {
00283             $this->chronProt->shutdownLB( $this->mainLB );
00284         }
00285         foreach ( $this->extLBs as $extLB ) {
00286             $this->chronProt->shutdownLB( $extLB );
00287         }
00288         $this->chronProt->shutdown();
00289         $this->commitMasterChanges();
00290     }
00291 }
00292 
00299 class LBFactory_Fake extends LBFactory {
00300     function __construct( $conf ) {
00301     }
00302 
00303     function newMainLB( $wiki = false ) {
00304         throw new DBAccessError;
00305     }
00306 
00307     function getMainLB( $wiki = false ) {
00308         throw new DBAccessError;
00309     }
00310 
00311     function newExternalLB( $cluster, $wiki = false ) {
00312         throw new DBAccessError;
00313     }
00314 
00315     function &getExternalLB( $cluster, $wiki = false ) {
00316         throw new DBAccessError;
00317     }
00318 
00319     function forEachLB( $callback, $params = array() ) {
00320     }
00321 }
00322 
00326 class DBAccessError extends MWException {
00327     function __construct() {
00328         parent::__construct( "Mediawiki tried to access the database via wfGetDB(). This is not allowed." );
00329     }
00330 }