Use MainWANObjectCache to improve performance

Bug: T278030
Change-Id: I7e8487ff9b2e7c9038bd058aa11cd844450b165a
This commit is contained in:
jenkins-bot 2021-10-05 14:38:02 +00:00 committed by Func
commit 120ae2bac0
2 changed files with 58 additions and 15 deletions

View file

@ -3,7 +3,7 @@
"author": "Tim Laqua", "author": "Tim Laqua",
"url": "https://www.mediawiki.org/wiki/Extension:Contribution_Scores", "url": "https://www.mediawiki.org/wiki/Extension:Contribution_Scores",
"descriptionmsg": "contributionscores-desc", "descriptionmsg": "contributionscores-desc",
"version": "1.26.0", "version": "1.26.1",
"type": "specialpage", "type": "specialpage",
"requires": { "requires": {
"MediaWiki": ">= 1.34.0" "MediaWiki": ">= 1.34.0"
@ -39,6 +39,10 @@
"value": false, "value": false,
"description": "Set to true to exclude bots users from the reporting." "description": "Set to true to exclude bots users from the reporting."
}, },
"ContribScoreIgnoreUsernames": {
"value": [],
"description": "Array of usernames to exclude from the reporting."
},
"ContribScoresUseRealName": { "ContribScoresUseRealName": {
"value": false, "value": false,
"description": "Set to true to use real user names when available." "description": "Set to true to use real user names when available."
@ -50,6 +54,10 @@
"ContribScoreUseRoughEditCount": { "ContribScoreUseRoughEditCount": {
"value": false, "value": false,
"description": "Set to true to use the rough number of edits in user table, for performance issue." "description": "Set to true to use the rough number of edits in user table, for performance issue."
},
"ContribScoreCacheTTL": {
"value": 30,
"description": "Cache the contribution scores data, in minutes."
} }
}, },
"manifest_version": 2 "manifest_version": 2

View file

@ -3,6 +3,8 @@
* \brief Contains code for the ContributionScores Class (extends SpecialPage). * \brief Contains code for the ContributionScores Class (extends SpecialPage).
*/ */
use MediaWiki\MediaWikiServices;
/// Special page class for the Contribution Scores extension /// Special page class for the Contribution Scores extension
/** /**
* Special page that generates a list of wiki contributors based * Special page that generates a list of wiki contributors based
@ -80,29 +82,24 @@ class ContributionScores extends IncludableSpecialPage {
return $parser->insertStripItem( $output, $parser->mStripState ); return $parser->insertStripItem( $output, $parser->mStripState );
} }
/// Generates a "Contribution Scores" table for a given LIMIT and date range
/** /**
* Function generates Contribution Scores tables in HTML format (not wikiText) * Function fetch Contribution Scores data from database
* *
* @param int $days Days in the past to run report for * @param int $days Days in the past to run report for
* @param int $limit Maximum number of users to return (default 50) * @param int $limit Maximum number of users to return (default 50)
* @param string|null $title The title of the table * @return array Data including the requested Contribution Scores.
* @param array $options array of options (default none; nosort/notools)
* @return string Html Table representing the requested Contribution Scores.
*/ */
function genContributionScoreTable( $days, $limit, $title = null, $options = 'none' ) { public static function getContributionScoreData( $days, $limit ) {
global $wgContribScoreIgnoreBots, $wgContribScoreIgnoreBlockedUsers, $wgContribScoresUseRealName, global $wgContribScoreIgnoreBots, $wgContribScoreIgnoreBlockedUsers, $wgContribScoreIgnoreUsernames,
$wgContribScoreUseRoughEditCount; $wgContribScoreUseRoughEditCount;
$opts = explode( ',', strtolower( $options ) );
$dbr = wfGetDB( DB_REPLICA ); $dbr = wfGetDB( DB_REPLICA );
$revQuery = ActorMigration::newMigration()->getJoin( 'rev_user' ); $revQuery = ActorMigration::newMigration()->getJoin( 'rev_user' );
$revQuery['tables'] = array_merge( [ 'revision' ], $revQuery['tables'] ); $revQuery['tables'] = array_merge( [ 'revision' ], $revQuery['tables'] );
$revUser = $revQuery['fields']['rev_user']; $revUser = $revQuery['fields']['rev_user'];
$revUsername = $revQuery['fields']['rev_user_text'];
$sqlWhere = []; $sqlWhere = [];
@ -136,6 +133,11 @@ class ContributionScores extends IncludableSpecialPage {
], __METHOD__ ); ], __METHOD__ );
} }
if ( count( $wgContribScoreIgnoreUsernames ) ) {
$listIgnoredUsernames = $dbr->makeList( $wgContribScoreIgnoreUsernames );
$sqlWhere[] = "{$revUsername} NOT IN ($listIgnoredUsernames)";
}
if ( $dbr->unionSupportsOrderAndLimit() ) { if ( $dbr->unionSupportsOrderAndLimit() ) {
$order = [ $order = [
'GROUP BY' => 'rev_user', 'GROUP BY' => 'rev_user',
@ -196,6 +198,25 @@ class ContributionScores extends IncludableSpecialPage {
] ]
] ]
); );
$ret = iterator_to_array( $res );
return $ret;
}
/// Generates a "Contribution Scores" table for a given LIMIT and date range
/**
* Function generates Contribution Scores tables in HTML format (not wikiText)
*
* @param int $days Days in the past to run report for
* @param int $limit Maximum number of users to return (default 50)
* @param string|null $title The title of the table
* @param array $options array of options (default none; nosort/notools)
* @return string Html Table representing the requested Contribution Scores.
*/
function genContributionScoreTable( $days, $limit, $title = null, $options = 'none' ) {
global $wgContribScoresUseRealName, $wgContribScoreCacheTTL;
$opts = explode( ',', strtolower( $options ) );
$sortable = in_array( 'nosort', $opts ) ? '' : ' sortable'; $sortable = in_array( 'nosort', $opts ) ? '' : ' sortable';
@ -207,11 +228,26 @@ class ContributionScores extends IncludableSpecialPage {
Html::element( 'th', [], $this->msg( 'contributionscores-changes' )->text() ) . Html::element( 'th', [], $this->msg( 'contributionscores-changes' )->text() ) .
Html::element( 'th', [], $this->msg( 'contributionscores-username' )->text() ); Html::element( 'th', [], $this->msg( 'contributionscores-username' )->text() );
$cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
$data = $cache->getWithSetCallback(
$cache->makeKey( 'contributionscores', 'data-' . (string)$days ),
$wgContribScoreCacheTTL * 60,
function () use ( $days ) {
// Use max limit, as limit doesn't matter with performance.
// Avoid purge multiple times since limit on transclusion can be vary.
return self::getContributionScoreData( $days, self::CONTRIBUTIONSCORES_MAXINCLUDELIMIT );
} );
$lang = $this->getLanguage();
$altrow = ''; $altrow = '';
$user_rank = 1; $user_rank = 1;
$lang = $this->getLanguage(); foreach ( $data as $row ) {
foreach ( $res as $row ) { if ( $user_rank > $limit ) {
break;
}
// Use real name if option used and real name present. // Use real name if option used and real name present.
if ( $wgContribScoresUseRealName && $row->user_real_name !== '' ) { if ( $wgContribScoresUseRealName && $row->user_real_name !== '' ) {
$userLink = Linker::userLink( $userLink = Linker::userLink(
@ -257,8 +293,7 @@ class ContributionScores extends IncludableSpecialPage {
$output .= Html::closeElement( 'tr' ); $output .= Html::closeElement( 'tr' );
$output .= Html::closeElement( 'table' ); $output .= Html::closeElement( 'table' );
$dbr->freeResult( $res ); // Transcluded on a normal wiki page.
if ( !empty( $title ) ) { if ( !empty( $title ) ) {
$output = Html::rawElement( 'table', $output = Html::rawElement( 'table',
[ [