From 1231546be76f9dc56ddef14e34e087e431d4fefa Mon Sep 17 00:00:00 2001 From: Tim Starling Date: Sun, 25 Jan 2004 13:27:53 +0000 Subject: [PATCH] new object - basic DB load balancer --- includes/LoadBalancer.php | 143 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 includes/LoadBalancer.php diff --git a/includes/LoadBalancer.php b/includes/LoadBalancer.php new file mode 100644 index 0000000000..a3116e2ce1 --- /dev/null +++ b/includes/LoadBalancer.php @@ -0,0 +1,143 @@ +mServers = array(); + $this->mLoads = array(); + $this->mConnections = array(); + $this->mUser = false; + $this->mPassword = false; + $this->mDbName = false; + $this->mFailFunction = false; + $this->mReadIndex = -1; + $this->mForce = -1; + } + + function newFromParams( $servers, $loads, $user, $password, $dbName, $failFunction = false ) + { + $lb = new LoadBalancer; + $lb->initialise( $servers, $loads, $user, $password, $dbName, $failFunction = false ); + return $lb; + } + + function initialise( $servers, $loads, $user, $password, $dbName, $failFunction = false ) + { + $this->mServers = $servers; + $this->mLoads = $loads; + $this->mUser = $user; + $this->mPassword = $password; + $this->mDbName = $dbName; + $this->mFailFunction = $failFunction; + $this->mReadIndex = -1; + $this->mWriteIndex = -1; + $this->mForce = -1; + $this->mConnections = array(); + wfSeedRandom(); + } + + # Given an array of non-normalised probabilities, this function will select + # an element and return the appropriate key + function pickRandom( $weights ) + { + if ( !is_array( $weights ) || count( $weights ) == 0 ) { + return false; + } + + $sum = 0; + foreach ( $weights as $w ) { + $sum += $w; + } + $rand = mt_rand() / RAND_MAX * $sum; + + $sum = 0; + foreach ( $weights as $i => $w ) { + $sum += $w; + if ( $sum >= $rand ) { + break; + } + } + return $i; + } + + function &getReader() + { + if ( $this->mForce >= 0 ) { + $conn =& $this->getConnection( $this->mForce ); + } else { + if ( $this->mReadIndex >= 0 ) { + $conn =& $this->getConnection( $this->mReadIndex ); + } else { + # $loads is $this->mLoads except with elements knocked out if they + # don't work + $loads = $this->mLoads; + do { + $i = pickRandom( $loads ); + if ( $i !== false ) { + $conn =& $this->getConnection( $i ); + if ( !$conn->isOpen() ) { + unset( $loads[$i] ); + } + } + } while ( $i !== false && !$conn->isOpen() ); + if ( $conn->isOpen() ) { + $this->mReadIndex = $i; + } + } + } + if ( $conn === false || !$conn->isOpen() ) { + $this->reportConnectionError( $conn ); + $conn = false; + } + return $conn; + } + + function &getConnection( $i, $fail = false ) + { + if ( !array_key_exists( $i, $this->mConnections) || !$this->mConnections[$i]->isOpen() ) { + $this->mConnections[$i] = Database::newFromParams( $this->mServers[$i], $this->mUser, + $this->mPassword, $this->mDbName, 1 ); + } + if ( !$this->mConnections[$i]->isOpen() ) { + wfDebug( "Failed to connect to database $i at {$this->mServers[$i]}\n" ); + if ( $fail ) { + $this->reportConnectionError( $this->mConnections[$i] ); + } + $this->mConnections[$i] = false; + } + return $this->mConnections[$i]; + } + + function reportConnectionError( &$conn ) + { + if ( !is_object( $conn ) ) { + $conn = new Database; + } + if ( $this->mFailFunction ) { + $conn->setFailFunction( $this->mFailFunction ); + } else { + $conn->setFailFunction( "wfEmergencyAbort" ); + } + $conn->reportConnectionError(); + } + + function &getWriter() + { + $c =& $this->getConnection( 0 ); + if ( !$c->isOpen() ) { + reportConnectionError( $conn ); + $c = false; + } + return $c; + } + + function force( $i ) + { + $this->mForce = $i; + } +} -- 2.20.1