2 # Database load balancing object
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();
15 $this->mPassword
= false;
16 $this->mDbName
= false;
17 $this->mFailFunction
= false;
18 $this->mReadIndex
= -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 );
29 function initialise( $servers, $loads, $user, $password, $dbName, $failFunction = false )
31 $this->mServers
= $servers;
32 $this->mLoads
= $loads;
34 $this->mPassword
= $password;
35 $this->mDbName
= $dbName;
36 $this->mFailFunction
= $failFunction;
37 $this->mReadIndex
= -1;
38 $this->mWriteIndex
= -1;
40 $this->mConnections
= array();
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 ) {
53 foreach ( $weights as $w ) {
56 $rand = mt_rand() / RAND_MAX
* $sum;
59 foreach ( $weights as $i => $w ) {
61 if ( $sum >= $rand ) {
70 if ( $this->mForce
>= 0 ) {
71 $conn =& $this->getConnection( $this->mForce
);
73 if ( $this->mReadIndex
>= 0 ) {
74 $conn =& $this->getConnection( $this->mReadIndex
);
76 # $loads is $this->mLoads except with elements knocked out if they
78 $loads = $this->mLoads
;
80 $i = pickRandom( $loads );
82 $conn =& $this->getConnection( $i );
83 if ( !$conn->isOpen() ) {
87 } while ( $i !== false && !$conn->isOpen() );
88 if ( $conn->isOpen() ) {
89 $this->mReadIndex
= $i;
93 if ( $conn === false ||
!$conn->isOpen() ) {
94 $this->reportConnectionError( $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" );
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
);
124 $conn->setFailFunction( "wfEmergencyAbort" );
126 $conn->reportConnectionError();
129 function &getWriter()
131 $c =& $this->getConnection( 0 );
132 if ( !$c->isOpen() ) {
133 reportConnectionError( $conn );