From: Aaron Schulz Date: Sun, 10 May 2015 18:15:25 +0000 (-0700) Subject: Avoid cache stampedes in ChangeTag class X-Git-Tag: 1.31.0-rc.0~11449^2 X-Git-Url: https://git.cyclocoop.org/?a=commitdiff_plain;h=3782a0d53bbe8b76baebebee92ffe9ca32f39d6c;p=lhc%2Fweb%2Fwiklou.git Avoid cache stampedes in ChangeTag class Change-Id: Ieec931c4211323ae7b838c783e45e1a83a7bb6a1 --- diff --git a/includes/changetags/ChangeTags.php b/includes/changetags/ChangeTags.php index 64f89bf099..7da25fe498 100644 --- a/includes/changetags/ChangeTags.php +++ b/includes/changetags/ChangeTags.php @@ -1064,22 +1064,18 @@ class ChangeTags { * @since 1.25 */ public static function listExtensionActivatedTags() { - $cache = ObjectCache::getMainWANInstance(); - - $key = wfMemcKey( 'active-tags' ); - $tags = $cache->get( $key ); - if ( $tags ) { - return $tags; - } - - // ask extensions which tags they consider active - $extensionActive = array(); - Hooks::run( 'ChangeTagsListActive', array( &$extensionActive ) ); - - // Short-term caching. - $cache->set( $key, $extensionActive, 300 ); - - return $extensionActive; + return ObjectCache::getMainWANInstance()->getWithSetCallback( + wfMemcKey( 'active-tags' ), + function() { + // Ask extensions which tags they consider active + $extensionActive = array(); + Hooks::run( 'ChangeTagsListActive', array( &$extensionActive ) ); + return $extensionActive; + }, + 300, + array( wfMemcKey( 'active-tags' ) ), + array( 'lockTSE' => INF ) + ); } /** @@ -1106,29 +1102,21 @@ class ChangeTags { * @since 1.25 */ public static function listExplicitlyDefinedTags() { - $cache = ObjectCache::getMainWANInstance(); - - $key = wfMemcKey( 'valid-tags-db' ); - $tags = $cache->get( $key ); - if ( $tags ) { - return $tags; - } - - $emptyTags = array(); - - // Some DB stuff - $dbr = wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'valid_tag', 'vt_tag', array(), __METHOD__ ); - foreach ( $res as $row ) { - $emptyTags[] = $row->vt_tag; - } - - $emptyTags = array_filter( array_unique( $emptyTags ) ); - - // Short-term caching. - $cache->set( $key, $emptyTags, 300 ); - - return $emptyTags; + $fname = __METHOD__; + + return ObjectCache::getMainWANInstance()->getWithSetCallback( + wfMemcKey( 'valid-tags-db' ), + function() use ( $fname ) { + $dbr = wfGetDB( DB_SLAVE ); + $tags = $dbr->selectFieldValues( + 'valid_tag', 'vt_tag', array(), $fname ); + + return array_filter( array_unique( $tags ) ); + }, + 300, + array( wfMemcKey( 'valid-tags-db' ) ), + array( 'lockTSE' => INF ) + ); } /** @@ -1141,22 +1129,17 @@ class ChangeTags { * @since 1.25 */ public static function listExtensionDefinedTags() { - $cache = ObjectCache::getMainWANInstance(); - - $key = wfMemcKey( 'valid-tags-hook' ); - $tags = $cache->get( $key ); - if ( $tags ) { - return $tags; - } - - $emptyTags = array(); - Hooks::run( 'ListDefinedTags', array( &$emptyTags ) ); - $emptyTags = array_filter( array_unique( $emptyTags ) ); - - // Short-term caching. - $cache->set( $key, $emptyTags, 300 ); - - return $emptyTags; + return ObjectCache::getMainWANInstance()->getWithSetCallback( + wfMemcKey( 'valid-tags-hook' ), + function() { + $tags = array(); + Hooks::run( 'ListDefinedTags', array( &$tags ) ); + return array_filter( array_unique( $tags ) ); + }, + 300, + array( wfMemcKey( 'valid-tags-hook' ) ), + array( 'lockTSE' => INF ) + ); } /** @@ -1167,9 +1150,9 @@ class ChangeTags { public static function purgeTagCacheAll() { $cache = ObjectCache::getMainWANInstance(); - $cache->delete( wfMemcKey( 'active-tags' ) ); - $cache->delete( wfMemcKey( 'valid-tags-db' ) ); - $cache->delete( wfMemcKey( 'valid-tags-hook' ) ); + $cache->touchCheckKey( wfMemcKey( 'active-tags' ) ); + $cache->touchCheckKey( wfMemcKey( 'valid-tags-db' ) ); + $cache->touchCheckKey( wfMemcKey( 'valid-tags-hook' ) ); self::purgeTagUsageCache(); } @@ -1194,38 +1177,38 @@ class ChangeTags { * @return array Array of string => int */ public static function tagUsageStatistics() { - $cache = ObjectCache::getMainWANInstance(); - - $key = wfMemcKey( 'change-tag-statistics' ); - $stats = $cache->get( $key ); - if ( $stats ) { - return $stats; - } - - $out = array(); + $fname = __METHOD__; + + return ObjectCache::getMainWANInstance()->getWithSetCallback( + wfMemcKey( 'change-tag-statistics' ), + function() use ( $fname ) { + $out = array(); + + $dbr = wfGetDB( DB_SLAVE, 'vslow' ); + $res = $dbr->select( + 'change_tag', + array( 'ct_tag', 'hitcount' => 'count(*)' ), + array(), + $fname, + array( 'GROUP BY' => 'ct_tag', 'ORDER BY' => 'hitcount DESC' ) + ); - $dbr = wfGetDB( DB_SLAVE, 'vslow' ); - $res = $dbr->select( - 'change_tag', - array( 'ct_tag', 'hitcount' => 'count(*)' ), - array(), - __METHOD__, - array( 'GROUP BY' => 'ct_tag', 'ORDER BY' => 'hitcount DESC' ) + foreach ( $res as $row ) { + $out[$row->ct_tag] = $row->hitcount; + } + + foreach ( ChangeTags::listDefinedTags() as $tag ) { + if ( !isset( $out[$tag] ) ) { + $out[$tag] = 0; + } + } + + return $out; + }, + 300, + array( wfMemcKey( 'change-tag-statistics' ) ), + array( 'lockTSE' => INF ) ); - - foreach ( $res as $row ) { - $out[$row->ct_tag] = $row->hitcount; - } - foreach ( self::listDefinedTags() as $tag ) { - if ( !isset( $out[$tag] ) ) { - $out[$tag] = 0; - } - } - - // Cache for a very short time - $cache->set( $key, $out, 300 ); - - return $out; } /**