X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2FCategory.php;h=c22ea64abf8c398a204c1035327e7e0cef3e3cfb;hp=ece32ea1059b67fdd0d8cbd1aaee0ce02b658f0d;hb=36395150104588f2afea866c330b683e4329fa48;hpb=c584722cc2e3d33edae58d46c2149063b3fc6d72 diff --git a/includes/Category.php b/includes/Category.php index ece32ea105..c22ea64abf 100644 --- a/includes/Category.php +++ b/includes/Category.php @@ -40,15 +40,19 @@ class Category { /** Counts of membership (cat_pages, cat_subcats, cat_files) */ private $mPages = null, $mSubcats = null, $mFiles = null; + const LOAD_ONLY = 0; + const LAZY_INIT_ROW = 1; + private function __construct() { } /** * Set up all member variables using a database query. + * @param integer $mode * @throws MWException * @return bool True on success, false on failure. */ - protected function initialize() { + protected function initialize( $mode = self::LOAD_ONLY ) { if ( $this->mName === null && $this->mID === null ) { throw new MWException( __METHOD__ . ' has both names and IDs null' ); } elseif ( $this->mID === null ) { @@ -80,7 +84,7 @@ class Category { $this->mFiles = 0; # If the title exists, call refreshCounts to add a row for it. - if ( $this->mTitle->exists() ) { + if ( $mode === self::LAZY_INIT_ROW && $this->mTitle->exists() ) { DeferredUpdates::addCallableUpdate( [ $this, 'refreshCounts' ] ); } @@ -104,7 +108,9 @@ class Category { $this->mSubcats = max( $this->mSubcats, 0 ); $this->mFiles = max( $this->mFiles, 0 ); - DeferredUpdates::addCallableUpdate( [ $this, 'refreshCounts' ] ); + if ( $mode === self::LAZY_INIT_ROW ) { + DeferredUpdates::addCallableUpdate( [ $this, 'refreshCounts' ] ); + } } return true; @@ -247,7 +253,7 @@ class Category { return $this->mTitle; } - if ( !$this->initialize() ) { + if ( !$this->initialize( self::LAZY_INIT_ROW ) ) { return false; } @@ -258,12 +264,11 @@ class Category { /** * Fetch a TitleArray of up to $limit category members, beginning after the * category sort key $offset. - * @param int $limit + * @param int|bool $limit * @param string $offset * @return TitleArray TitleArray object for category members. */ public function getMembers( $limit = false, $offset = '' ) { - $dbr = wfGetDB( DB_REPLICA ); $conds = [ 'cl_to' => $this->getName(), 'cl_from = page_id' ]; @@ -297,7 +302,7 @@ class Category { * @return bool */ private function getX( $key ) { - if ( !$this->initialize() ) { + if ( !$this->initialize( self::LAZY_INIT_ROW ) ) { return false; } return $this->{$key}; @@ -316,11 +321,18 @@ class Category { # If we have just a category name, find out whether there is an # existing row. Or if we have just an ID, get the name, because # that's what categorylinks uses. - if ( !$this->initialize() ) { + if ( !$this->initialize( self::LOAD_ONLY ) ) { return false; } $dbw = wfGetDB( DB_MASTER ); + # Avoid excess contention on the same category (T162121) + $name = __METHOD__ . ':' . md5( $this->mName ); + $scopedLock = $dbw->getScopedLockAndFlush( $name, __METHOD__, 1 ); + if ( !$scopedLock ) { + return false; + } + $dbw->startAtomic( __METHOD__ ); $cond1 = $dbw->conditional( [ 'page_namespace' => NS_CATEGORY ], 1, 'NULL' );