khtml fix stylesheet
[mediawiki.git] / includes / LoadBalancer.php
blob3df2ac58c604e7e2a20beac127645230e9ec4a4c
1 <?php
2 # Database load balancing object
4 class LoadBalancer {
5 /* private */ var $mServers, $mConnections, $mLoads;
6 /* private */ var $mUser, $mPassword, $mDbName, $mFailFunction;
7 /* private */ var $mForce, $mReadIndex;
9 function LoadBalancer()
11 $this->mServers = array();
12 $this->mLoads = array();
13 $this->mConnections = array();
14 $this->mUser = false;
15 $this->mPassword = false;
16 $this->mDbName = false;
17 $this->mFailFunction = false;
18 $this->mReadIndex = -1;
19 $this->mForce = -1;
22 function newFromParams( $servers, $loads, $user, $password, $dbName, $failFunction = false )
24 $lb = new LoadBalancer;
25 $lb->initialise( $servers, $loads, $user, $password, $dbName, $failFunction = false );
26 return $lb;
29 function initialise( $servers, $loads, $user, $password, $dbName, $failFunction = false )
31 $this->mServers = $servers;
32 $this->mLoads = $loads;
33 $this->mUser = $user;
34 $this->mPassword = $password;
35 $this->mDbName = $dbName;
36 $this->mFailFunction = $failFunction;
37 $this->mReadIndex = -1;
38 $this->mWriteIndex = -1;
39 $this->mForce = -1;
40 $this->mConnections = array();
41 wfSeedRandom();
44 # Given an array of non-normalised probabilities, this function will select
45 # an element and return the appropriate key
46 function pickRandom( $weights )
48 if ( !is_array( $weights ) || count( $weights ) == 0 ) {
49 return false;
52 $sum = 0;
53 foreach ( $weights as $w ) {
54 $sum += $w;
56 $rand = mt_rand() / RAND_MAX * $sum;
58 $sum = 0;
59 foreach ( $weights as $i => $w ) {
60 $sum += $w;
61 if ( $sum >= $rand ) {
62 break;
65 return $i;
68 function &getReader()
70 if ( $this->mForce >= 0 ) {
71 $conn =& $this->getConnection( $this->mForce );
72 } else {
73 if ( $this->mReadIndex >= 0 ) {
74 $conn =& $this->getConnection( $this->mReadIndex );
75 } else {
76 # $loads is $this->mLoads except with elements knocked out if they
77 # don't work
78 $loads = $this->mLoads;
79 do {
80 $i = pickRandom( $loads );
81 if ( $i !== false ) {
82 $conn =& $this->getConnection( $i );
83 if ( !$conn->isOpen() ) {
84 unset( $loads[$i] );
87 } while ( $i !== false && !$conn->isOpen() );
88 if ( $conn->isOpen() ) {
89 $this->mReadIndex = $i;
93 if ( $conn === false || !$conn->isOpen() ) {
94 $this->reportConnectionError( $conn );
95 $conn = false;
97 return $conn;
100 function &getConnection( $i, $fail = false )
102 if ( !array_key_exists( $i, $this->mConnections) || !$this->mConnections[$i]->isOpen() ) {
103 $this->mConnections[$i] = Database::newFromParams( $this->mServers[$i], $this->mUser,
104 $this->mPassword, $this->mDbName, 1 );
106 if ( !$this->mConnections[$i]->isOpen() ) {
107 wfDebug( "Failed to connect to database $i at {$this->mServers[$i]}\n" );
108 if ( $fail ) {
109 $this->reportConnectionError( $this->mConnections[$i] );
111 $this->mConnections[$i] = false;
113 return $this->mConnections[$i];
116 function reportConnectionError( &$conn )
118 if ( !is_object( $conn ) ) {
119 $conn = new Database;
121 if ( $this->mFailFunction ) {
122 $conn->setFailFunction( $this->mFailFunction );
123 } else {
124 $conn->setFailFunction( "wfEmergencyAbort" );
126 $conn->reportConnectionError();
129 function &getWriter()
131 $c =& $this->getConnection( 0 );
132 if ( !$c->isOpen() ) {
133 reportConnectionError( $conn );
134 $c = false;
136 return $c;
139 function force( $i )
141 $this->mForce = $i;