From: Aaron Date: Thu, 10 May 2012 22:42:59 +0000 (-0700) Subject: [SiteStatsUpdate] Reduced contention by using a new lockIsFree() DB function. X-Git-Tag: 1.31.0-rc.0~23648^2 X-Git-Url: https://git.cyclocoop.org/%7B%7B%20url_for%28%27votes%27%2C%20votes=%27waiting%27%29%20%7D%7D?a=commitdiff_plain;h=ff187ea7cc0afe9b4ccc87209c2dda6cab62f6f1;p=lhc%2Fweb%2Fwiklou.git [SiteStatsUpdate] Reduced contention by using a new lockIsFree() DB function. * Note: follows up a4b3979160c3ae895d4763967c485380448ce8c0 * Cleanup up transaction statements a bit; transactions don't effect the lock calls * Also made DatabaseMysql::unlock() actually return a bool Change-Id: Iade2efa94165b6918eae0863716cc163f36a07b8 --- diff --git a/includes/SiteStats.php b/includes/SiteStats.php index fec24e910c..10aed9cc9a 100644 --- a/includes/SiteStats.php +++ b/includes/SiteStats.php @@ -286,14 +286,13 @@ class SiteStatsUpdate implements DeferrableUpdate { $this->doUpdatePendingDeltas(); } else { $dbw = wfGetDB( DB_MASTER ); - // Need a separate transaction because this a global lock - $dbw->begin( __METHOD__ ); $lockKey = wfMemcKey( 'site_stats' ); // prepend wiki ID if ( $rate ) { // Lock the table so we don't have double DB/memcached updates - if ( !$dbw->lock( $lockKey, __METHOD__, 1 ) ) { - $dbw->commit( __METHOD__ ); + if ( !$dbw->lockIsFree( $lockKey, __METHOD__ ) + || !$dbw->lock( $lockKey, __METHOD__, 1 ) // 1 sec timeout + ) { $this->doUpdatePendingDeltas(); return; } @@ -307,6 +306,9 @@ class SiteStatsUpdate implements DeferrableUpdate { $this->images += ( $pd['ss_images']['+'] - $pd['ss_images']['-'] ); } + // Need a separate transaction because this a global lock + $dbw->begin( __METHOD__ ); + // Build up an SQL query of deltas and apply them... $updates = ''; $this->appendUpdate( $updates, 'ss_total_views', $this->views ); diff --git a/includes/db/Database.php b/includes/db/Database.php index 6eb51afc75..b972f3b140 100644 --- a/includes/db/Database.php +++ b/includes/db/Database.php @@ -3364,6 +3364,18 @@ abstract class DatabaseBase implements DatabaseType { return 'CONCAT(' . implode( ',', $stringList ) . ')'; } + /** + * Check to see if a named lock is available. This is non-blocking. + * + * @param $lockName String: name of lock to poll + * @param $method String: name of method calling us + * @return Boolean + * @since 1.20 + */ + public function lockIsFree( $lockName, $method ) { + return true; + } + /** * Acquire a named lock * diff --git a/includes/db/DatabaseMysql.php b/includes/db/DatabaseMysql.php index c334c388d8..8550635a39 100644 --- a/includes/db/DatabaseMysql.php +++ b/includes/db/DatabaseMysql.php @@ -686,6 +686,21 @@ class DatabaseMysql extends DatabaseBase { return parent::streamStatementEnd( $sql, $newLine ); } + /** + * Check to see if a named lock is available. This is non-blocking. + * + * @param $lockName String: name of lock to poll + * @param $method String: name of method calling us + * @return Boolean + * @since 1.20 + */ + public function lockIsFree( $lockName, $method ) { + $lockName = $this->addQuotes( $lockName ); + $result = $this->query( "SELECT IS_FREE_LOCK($lockName) AS lockstatus", $method ); + $row = $this->fetchObject( $result ); + return ( $row->lockstatus == 1 ); + } + /** * @param $lockName string * @param $method string @@ -715,7 +730,7 @@ class DatabaseMysql extends DatabaseBase { $lockName = $this->addQuotes( $lockName ); $result = $this->query( "SELECT RELEASE_LOCK($lockName) as lockstatus", $method ); $row = $this->fetchObject( $result ); - return $row->lockstatus; + return ( $row->lockstatus == 1 ); } /**