<?php
/**
+ * Generator of database load balancing objects
+ *
* @file
* @ingroup Database
*/
* @ingroup Database
*/
abstract class LBFactory {
+
+ /**
+ * @var LBFactory
+ */
static $instance;
+ /**
+ * Disables all access to the load balancer, will cause all database access
+ * to throw a DBAccessError
+ */
+ public static function disableBackend() {
+ global $wgLBFactoryConf;
+ self::$instance = new LBFactory_Fake( $wgLBFactoryConf );
+ }
+
/**
* Get an LBFactory instance
+ *
+ * @return LBFactory
*/
static function &singleton() {
if ( is_null( self::$instance ) ) {
/**
* Shut down, close connections and destroy the cached instance.
- *
+ *
*/
static function destroyInstance() {
if ( self::$instance ) {
}
}
+ /**
+ * Set the instance to be the given object
+ *
+ * @param $instance LBFactory
+ */
+ static function setInstance( $instance ) {
+ self::destroyInstance();
+ self::$instance = $instance;
+ }
+
/**
* Construct a factory based on a configuration array (typically from $wgLBFactoryConf)
*/
abstract function __construct( $conf );
/**
- * Create a new load balancer object. The resulting object will be untracked,
+ * Create a new load balancer object. The resulting object will be untracked,
* not chronology-protected, and the caller is responsible for cleaning it up.
*
- * @param string $wiki Wiki ID, or false for the current wiki
+ * @param $wiki String: wiki ID, or false for the current wiki
* @return LoadBalancer
*/
abstract function newMainLB( $wiki = false );
/**
* Get a cached (tracked) load balancer object.
*
- * @param string $wiki Wiki ID, or false for the current wiki
+ * @param $wiki String: wiki ID, or false for the current wiki
* @return LoadBalancer
*/
abstract function getMainLB( $wiki = false );
- /*
- * Create a new load balancer for external storage. The resulting object will be
- * untracked, not chronology-protected, and the caller is responsible for
+ /**
+ * Create a new load balancer for external storage. The resulting object will be
+ * untracked, not chronology-protected, and the caller is responsible for
* cleaning it up.
*
- * @param string $cluster External storage cluster, or false for core
- * @param string $wiki Wiki ID, or false for the current wiki
+ * @param $cluster String: external storage cluster, or false for core
+ * @param $wiki String: wiki ID, or false for the current wiki
+ *
+ * @return LoadBalancer
*/
abstract function newExternalLB( $cluster, $wiki = false );
- /*
+ /**
* Get a cached (tracked) load balancer for external storage
*
- * @param string $cluster External storage cluster, or false for core
- * @param string $wiki Wiki ID, or false for the current wiki
+ * @param $cluster String: external storage cluster, or false for core
+ * @param $wiki String: wiki ID, or false for the current wiki
+ *
+ * @return LoadBalancer
*/
abstract function &getExternalLB( $cluster, $wiki = false );
* A simple single-master LBFactory that gets its configuration from the b/c globals
*/
class LBFactory_Simple extends LBFactory {
+
+ /**
+ * @var LoadBalancer
+ */
var $mainLB;
var $extLBs = array();
$this->chronProt = new ChronologyProtector;
}
+ /**
+ * @param $wiki
+ * @return LoadBalancer
+ */
function newMainLB( $wiki = false ) {
global $wgDBservers, $wgMasterWaitTimeout;
if ( $wgDBservers ) {
}
return new LoadBalancer( array(
- 'servers' => $servers,
- 'masterWaitTimeout' => $wgMasterWaitTimeout
+ 'servers' => $servers,
+ 'masterWaitTimeout' => $wgMasterWaitTimeout
));
}
+ /**
+ * @param $wiki
+ * @return LoadBalancer
+ */
function getMainLB( $wiki = false ) {
if ( !isset( $this->mainLB ) ) {
$this->mainLB = $this->newMainLB( $wiki );
return $this->mainLB;
}
+ /**
+ * @throws MWException
+ * @param $cluster
+ * @param $wiki
+ * @return LoadBalancer
+ */
function newExternalLB( $cluster, $wiki = false ) {
global $wgExternalServers;
if ( !isset( $wgExternalServers[$cluster] ) ) {
throw new MWException( __METHOD__.": Unknown cluster \"$cluster\"" );
}
return new LoadBalancer( array(
- 'servers' => $wgExternalServers[$cluster]
+ 'servers' => $wgExternalServers[$cluster]
));
}
+ /**
+ * @param $cluster
+ * @param $wiki
+ * @return array
+ */
function &getExternalLB( $cluster, $wiki = false ) {
if ( !isset( $this->extLBs[$cluster] ) ) {
$this->extLBs[$cluster] = $this->newExternalLB( $cluster, $wiki );
}
}
+/**
+ * LBFactory class that throws an error on any attempt to use it.
+ * This will typically be done via wfGetDB().
+ * Call LBFactory::disableBackend() to start using this, and
+ * LBFactory::enableBackend() to return to normal behavior
+ */
+class LBFactory_Fake extends LBFactory {
+ function __construct( $conf ) {}
+
+ function newMainLB( $wiki = false) {
+ throw new DBAccessError;
+ }
+ function getMainLB( $wiki = false ) {
+ throw new DBAccessError;
+ }
+ function newExternalLB( $cluster, $wiki = false ) {
+ throw new DBAccessError;
+ }
+ function &getExternalLB( $cluster, $wiki = false ) {
+ throw new DBAccessError;
+ }
+ function forEachLB( $callback, $params = array() ) {}
+}
+
+/**
+ * Exception class for attempted DB access
+ */
+class DBAccessError extends MWException {
+ function __construct() {
+ parent::__construct( "Mediawiki tried to access the database via wfGetDB(). This is not allowed." );
+ }
+}
+
/**
* Class for ensuring a consistent ordering of events as seen by the user, despite replication.
* Kind of like Hawking's [[Chronology Protection Agency]].
/**
* Initialise a LoadBalancer to give it appropriate chronology protection.
*
- * @param LoadBalancer $lb
+ * @param $lb LoadBalancer
*/
function initLB( $lb ) {
if ( $this->startupPos === null ) {
* Notify the ChronologyProtector that the LoadBalancer is about to shut
* down. Saves replication positions.
*
- * @param LoadBalancer $lb
+ * @param $lb LoadBalancer
*/
function shutdownLB( $lb ) {
// Don't start a session, don't bother with non-replicated setups