From: Brad Jorsch Date: Tue, 19 Nov 2019 19:36:35 +0000 (-0500) Subject: SpecialContributions: Use PoolCounter to limit concurrency X-Git-Tag: 1.34.2~4 X-Git-Url: http://git.cyclocoop.org/?a=commitdiff_plain;ds=sidebyside;h=48c3e3231e017fb1001e60fb2c49dbe78b35f0f1;p=lhc%2Fweb%2Fwiklou.git 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.34 b/RELEASE-NOTES-1.34 index d035653201..dcc6a39d7f 100644 --- a/RELEASE-NOTES-1.34 +++ b/RELEASE-NOTES-1.34 @@ -6,6 +6,8 @@ THIS IS NOT A RELEASE YET === Changes since MediaWiki 1.34.1 === * The MultiHttpClient code will fallover to non-curl if curl_multi* is blocked. +* Per-user concurrency in SpecialContributions can now be limited by setting + $wgPoolCounterConf['SpecialContributions'] appropriately. == MediaWiki 1.34.1 == diff --git a/includes/specials/SpecialContributions.php b/includes/specials/SpecialContributions.php index 8f92cd5f9d..c39094e4dc 100644 --- a/includes/specials/SpecialContributions.php +++ b/includes/specials/SpecialContributions.php @@ -239,19 +239,38 @@ class SpecialContributions extends IncludableSpecialPage { } elseif ( !$pager->getNumRows() ) { $out->addWikiMsg( 'nocontribs', $target ); } else { - # Show a message about replica DB lag, if applicable - $lag = $pager->getDatabase()->getSessionLagStatus()['lag']; - 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 + $lag = $pager->getDatabase()->getSessionLagStatus()['lag']; + 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 7c4eeb692b..24e00ade49 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -2601,6 +2601,8 @@ "sp-contributions-footer-anon": "-", "sp-contributions-footer-anon-range": "-", "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 d21857cac3..56c700de44 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -2807,6 +2807,8 @@ "sp-contributions-footer-anon": "{{ignored}}This is the footer for anonymous users on [[Special:Contributions]].", "sp-contributions-footer-anon-range": "{{ignored}}This is the footer for IP ranges 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}}",