From: Brad Jorsch Date: Tue, 19 Nov 2019 19:36:35 +0000 (-0500) Subject: SpecialContributions: Use PoolCounter to limit concurrency X-Git-Tag: 1.31.8~4 X-Git-Url: http://git.cyclocoop.org/?p=lhc%2Fweb%2Fwiklou.git;a=commitdiff_plain;h=4d081c8cd944f54117ec8bd12191d48d75f4d83e SpecialContributions: Use PoolCounter to limit concurrency Allow using PoolCounter to limit the number of times a user or IP can concurrently load Special:Contributions. By default no limitation is applied. Key 'SpecialContributions' in $wgPoolCounterConf must be set to configure the concurrency. Bug: T234450 Change-Id: Ie769fa170093bfb6d281c651d3857545d139e009 --- diff --git a/RELEASE-NOTES-1.31 b/RELEASE-NOTES-1.31 index bde7d57d8a..88f43aa3d5 100644 --- a/RELEASE-NOTES-1.31 +++ b/RELEASE-NOTES-1.31 @@ -3,6 +3,8 @@ THIS IS NOT A RELEASE YET === Changes since MediaWiki 1.31.7 === +* Per-user concurrency in SpecialContributions can now be limited by setting + $wgPoolCounterConf['SpecialContributions'] appropriately. == MediaWiki 1.31.7 == diff --git a/includes/specials/SpecialContributions.php b/includes/specials/SpecialContributions.php index 6fc8306a52..2812541c16 100644 --- a/includes/specials/SpecialContributions.php +++ b/includes/specials/SpecialContributions.php @@ -230,20 +230,39 @@ class SpecialContributions extends IncludableSpecialPage { } elseif ( !$pager->getNumRows() ) { $out->addWikiMsg( 'nocontribs', $target ); } else { - # Show a message about replica DB lag, if applicable - $lb = MediaWikiServices::getInstance()->getDBLoadBalancer(); - $lag = $lb->safeGetLag( $pager->getDatabase() ); - if ( $lag > 0 ) { - $out->showLagWarning( $lag ); - } - - $output = $pager->getBody(); - if ( !$this->including() ) { - $output = '

' . $pager->getNavigationBar() . '

' . - $output . - '

' . $pager->getNavigationBar() . '

'; + // @todo We just want a wiki ID here, not a "DB domain", but + // current status of MediaWiki conflates the two. See T235955. + $poolKey = WikiMap::getCurrentWikiDbDomain() . ':SpecialContributions:'; + if ( $this->getUser()->isAnon() ) { + $poolKey .= 'a:' . $this->getUser()->getName(); + } else { + $poolKey .= 'u:' . $this->getUser()->getId(); } - $out->addHTML( $output ); + $work = new PoolCounterWorkViaCallback( 'SpecialContributions', $poolKey, [ + 'doWork' => function () use ( $pager, $out ) { + # Show a message about replica DB lag, if applicable + $lb = MediaWikiServices::getInstance()->getDBLoadBalancer(); + $lag = $lb->safeGetLag( $pager->getDatabase() ); + if ( $lag > 0 ) { + $out->showLagWarning( $lag ); + } + + $output = $pager->getBody(); + if ( !$this->including() ) { + $output = '

' . $pager->getNavigationBar() . '

' . + $output . + '

' . $pager->getNavigationBar() . '

'; + } + $out->addHTML( $output ); + }, + 'error' => function () use ( $out ) { + $msg = $this->getUser()->isAnon() + ? 'sp-contributions-concurrency-ip' + : 'sp-contributions-concurrency-user'; + $out->wrapWikiMsg( "
\n$1\n
", $msg ); + } + ] ); + $work->execute(); } $out->preventClickjacking( $pager->getPreventClickjacking() ); diff --git a/languages/i18n/en.json b/languages/i18n/en.json index 86762384a8..13920c0b15 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -2521,6 +2521,8 @@ "sp-contributions-footer-anon-range": "-", "sp-contributions-footer-newbies": "-", "sp-contributions-outofrange": "Unable to show any results. The requested IP range is larger than the CIDR limit of /$1.", + "sp-contributions-concurrency-user": "Sorry, too many requests are being made from your user account. Please try again later.", + "sp-contributions-concurrency-ip": "Sorry, too many requests are being made from your IP address. Please try again later.", "whatlinkshere": "What links here", "whatlinkshere-title": "Pages that link to \"$1\"", "whatlinkshere-summary": "", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index 576c2bf241..e745375132 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -2718,6 +2718,8 @@ "sp-contributions-footer-anon-range": "{{ignored}}This is the footer for IP ranges on [[Special:Contributions]].", "sp-contributions-footer-newbies": "{{ignored}}This is the footer for newbie users on [[Special:Contributions]].", "sp-contributions-outofrange": "Message shown when a user tries to view contributions of an IP range that's too large. $1 is the numerical limit imposed on the CIDR range.", + "sp-contributions-concurrency-user": "Message shown when a logged-in user tries to load [[Special:Contributions]] too many times at once.", + "sp-contributions-concurrency-ip": "Message shown when a logged-out user tries to load [[Special:Contributions]] too many times at once.", "whatlinkshere": "The text of the link in the toolbox (on the left, below the search menu) going to [[Special:WhatLinksHere]].\n\nSee also:\n* {{msg-mw|Whatlinkshere}}\n* {{msg-mw|Accesskey-t-whatlinkshere}}\n* {{msg-mw|Tooltip-t-whatlinkshere}}", "whatlinkshere-title": "Title of the special page [[Special:WhatLinksHere]]. This page appears when you click on the 'What links here' button in the toolbox. $1 is the name of the page concerned.", "whatlinkshere-summary": "{{doc-specialpagesummary|whatlinkshere}}",