Salvage site_stats row with negative values in miser mode
* Instead of returning all zeroes, just use zero for the negative values in the row. * Allow large numbers since the fields are BIGINT. * Clean up the return types to truly be integers. * Respect the $groups argument in SiteStatsInit::getDB(). Bug: T186947 Change-Id: I51fdc45124c12aba114540fc0ec66a3e63d61e09
This commit is contained in:
parent
09a1f4776e
commit
6535091de2
2 changed files with 46 additions and 27 deletions
|
|
@ -56,13 +56,13 @@ class SiteStats {
|
|||
wfDebug( __METHOD__ . ": reading site_stats from replica DB\n" );
|
||||
$row = self::doLoadFromDB( $dbr );
|
||||
|
||||
if ( !self::isSane( $row ) && $lb->hasOrMadeRecentMasterChanges() ) {
|
||||
if ( !self::isRowSane( $row ) && $lb->hasOrMadeRecentMasterChanges() ) {
|
||||
// Might have just been initialized during this request? Underflow?
|
||||
wfDebug( __METHOD__ . ": site_stats damaged or missing on replica DB\n" );
|
||||
$row = self::doLoadFromDB( $lb->getConnection( DB_MASTER ) );
|
||||
}
|
||||
|
||||
if ( !self::isSane( $row ) ) {
|
||||
if ( !self::isRowSane( $row ) ) {
|
||||
if ( $config->get( 'MiserMode' ) ) {
|
||||
// Start off with all zeroes, assuming that this is a new wiki or any
|
||||
// repopulations where done manually via script.
|
||||
|
|
@ -79,35 +79,22 @@ class SiteStats {
|
|||
$row = self::doLoadFromDB( $lb->getConnection( DB_MASTER ) );
|
||||
}
|
||||
|
||||
if ( !self::isSane( $row ) ) {
|
||||
if ( !self::isRowSane( $row ) ) {
|
||||
wfDebug( __METHOD__ . ": site_stats persistently nonsensical o_O\n" );
|
||||
// Always return a row-like object
|
||||
$row = (object)array_fill_keys( self::selectFields(), 0 );
|
||||
$row = self::salvageInsaneRow( $row );
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IDatabase $db
|
||||
* @return stdClass|bool
|
||||
*/
|
||||
private static function doLoadFromDB( IDatabase $db ) {
|
||||
return $db->selectRow(
|
||||
'site_stats',
|
||||
self::selectFields(),
|
||||
[ 'ss_row_id' => 1 ],
|
||||
__METHOD__
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public static function edits() {
|
||||
self::load();
|
||||
|
||||
return self::$row->ss_total_edits;
|
||||
return (int)self::$row->ss_total_edits;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -116,7 +103,7 @@ class SiteStats {
|
|||
public static function articles() {
|
||||
self::load();
|
||||
|
||||
return self::$row->ss_good_articles;
|
||||
return (int)self::$row->ss_good_articles;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -125,7 +112,7 @@ class SiteStats {
|
|||
public static function pages() {
|
||||
self::load();
|
||||
|
||||
return self::$row->ss_total_pages;
|
||||
return (int)self::$row->ss_total_pages;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -134,7 +121,7 @@ class SiteStats {
|
|||
public static function users() {
|
||||
self::load();
|
||||
|
||||
return self::$row->ss_users;
|
||||
return (int)self::$row->ss_users;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -143,7 +130,7 @@ class SiteStats {
|
|||
public static function activeUsers() {
|
||||
self::load();
|
||||
|
||||
return self::$row->ss_active_users;
|
||||
return (int)self::$row->ss_active_users;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -152,7 +139,7 @@ class SiteStats {
|
|||
public static function images() {
|
||||
self::load();
|
||||
|
||||
return self::$row->ss_images;
|
||||
return (int)self::$row->ss_images;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -245,6 +232,19 @@ class SiteStats {
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IDatabase $db
|
||||
* @return stdClass|bool
|
||||
*/
|
||||
private static function doLoadFromDB( IDatabase $db ) {
|
||||
return $db->selectRow(
|
||||
'site_stats',
|
||||
self::selectFields(),
|
||||
[ 'ss_row_id' => 1 ],
|
||||
__METHOD__
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the provided row of site stats sane, or should it be regenerated?
|
||||
*
|
||||
|
|
@ -253,7 +253,7 @@ class SiteStats {
|
|||
* @param bool|object $row
|
||||
* @return bool
|
||||
*/
|
||||
private static function isSane( $row ) {
|
||||
private static function isRowSane( $row ) {
|
||||
if ( $row === false
|
||||
|| $row->ss_total_pages < $row->ss_good_articles
|
||||
|| $row->ss_total_edits < $row->ss_total_pages
|
||||
|
|
@ -268,7 +268,7 @@ class SiteStats {
|
|||
'ss_users',
|
||||
'ss_images',
|
||||
] as $member ) {
|
||||
if ( $row->$member > 2000000000 || $row->$member < 0 ) {
|
||||
if ( $row->$member < 0 ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -276,6 +276,22 @@ class SiteStats {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stdClass|bool $row
|
||||
* @return stdClass
|
||||
*/
|
||||
private static function salvageInsaneRow( $row ) {
|
||||
$map = $row ? (array)$row : [];
|
||||
// Fill in any missing values with zero
|
||||
$map += array_fill_keys( self::selectFields(), 0 );
|
||||
// Convert negative values to zero
|
||||
foreach ( $map as $field => $value ) {
|
||||
$map[$field] = max( 0, $value );
|
||||
}
|
||||
|
||||
return (object)$row;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LoadBalancer
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -198,9 +198,12 @@ class SiteStatsInit {
|
|||
|
||||
/**
|
||||
* @param int $index
|
||||
* @param string[] $groups
|
||||
* @return IDatabase
|
||||
*/
|
||||
private static function getDB( $index ) {
|
||||
return MediaWikiServices::getInstance()->getDBLoadBalancer()->getConnection( $index );
|
||||
private static function getDB( $index, $groups = [] ) {
|
||||
$lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
|
||||
|
||||
return $lb->getConnection( $index, $groups );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue