static function jobs() {
if ( !isset( self::$jobs ) ) {
$dbr = wfGetDB( DB_SLAVE );
- self::$jobs = $dbr->estimateRowCount( 'job' );
+ self::$jobs = array_sum( JobQueueGroup::singleton()->getQueueSizes() );
/* Zero rows still do single row read for row that doesn't exist, but people are annoyed by that */
if ( self::$jobs == 1 ) {
self::$jobs = 0;
* @return bool
*/
private static function isSane( $row ) {
- if (
- $row === false
+ if ( $row === false
|| $row->ss_total_pages < $row->ss_good_articles
|| $row->ss_total_edits < $row->ss_total_pages
+ || $row->ss_users < $row->ss_active_users
) {
return false;
}
// Now check for underflow/overflow
- foreach ( array( 'total_views', 'total_edits', 'good_articles',
- 'total_pages', 'users', 'images' ) as $member ) {
- if (
- $row->{"ss_$member"} > 2000000000
- || $row->{"ss_$member"} < 0
- ) {
+ foreach ( array(
+ 'ss_total_views',
+ 'ss_total_edits',
+ 'ss_good_articles',
+ 'ss_total_pages',
+ 'ss_users',
+ 'ss_active_users',
+ 'ss_images',
+ ) as $member ) {
+ if ( $row->$member > 2000000000 || $row->$member < 0 ) {
return false;
}
}
protected $users = 0;
protected $images = 0;
- // @TODO: deprecate this constructor
+ // @todo deprecate this constructor
function __construct( $views, $edits, $good, $pages = 0, $users = 0 ) {
$this->views = $views;
$this->edits = $edits;
if ( $rate && ( $rate < 0 || mt_rand( 0, $rate - 1 ) != 0 ) ) {
$this->doUpdatePendingDeltas();
} else {
- $dbw = wfGetDB( DB_MASTER );
-
- $lockKey = wfMemcKey( 'site_stats' ); // prepend wiki ID
- if ( $rate ) {
- // Lock the table so we don't have double DB/memcached updates
- if ( !$dbw->lockIsFree( $lockKey, __METHOD__ )
- || !$dbw->lock( $lockKey, __METHOD__, 1 ) // 1 sec timeout
- ) {
- $this->doUpdatePendingDeltas();
- return;
- }
- $pd = $this->getPendingDeltas();
- // Piggy-back the async deltas onto those of this stats update....
- $this->views += ( $pd['ss_total_views']['+'] - $pd['ss_total_views']['-'] );
- $this->edits += ( $pd['ss_total_edits']['+'] - $pd['ss_total_edits']['-'] );
- $this->articles += ( $pd['ss_good_articles']['+'] - $pd['ss_good_articles']['-'] );
- $this->pages += ( $pd['ss_total_pages']['+'] - $pd['ss_total_pages']['-'] );
- $this->users += ( $pd['ss_users']['+'] - $pd['ss_users']['-'] );
- $this->images += ( $pd['ss_images']['+'] - $pd['ss_images']['-'] );
- }
-
// Need a separate transaction because this a global lock
- $dbw->begin( __METHOD__ );
-
- // Build up an SQL query of deltas and apply them...
- $updates = '';
- $this->appendUpdate( $updates, 'ss_total_views', $this->views );
- $this->appendUpdate( $updates, 'ss_total_edits', $this->edits );
- $this->appendUpdate( $updates, 'ss_good_articles', $this->articles );
- $this->appendUpdate( $updates, 'ss_total_pages', $this->pages );
- $this->appendUpdate( $updates, 'ss_users', $this->users );
- $this->appendUpdate( $updates, 'ss_images', $this->images );
- if ( $updates != '' ) {
- $dbw->update( 'site_stats', array( $updates ), array(), __METHOD__ );
- }
+ wfGetDB( DB_MASTER )->onTransactionIdle( array( $this, 'tryDBUpdateInternal' ) );
+ }
+ }
- if ( $rate ) {
- // Decrement the async deltas now that we applied them
- $this->removePendingDeltas( $pd );
- // Commit the updates and unlock the table
- $dbw->unlock( $lockKey, __METHOD__ );
+ /**
+ * Do not call this outside of SiteStatsUpdate
+ *
+ * @return void
+ */
+ public function tryDBUpdateInternal() {
+ global $wgSiteStatsAsyncFactor;
+
+ $dbw = wfGetDB( DB_MASTER );
+ $lockKey = wfMemcKey( 'site_stats' ); // prepend wiki ID
+ if ( $wgSiteStatsAsyncFactor ) {
+ // Lock the table so we don't have double DB/memcached updates
+ if ( !$dbw->lockIsFree( $lockKey, __METHOD__ )
+ || !$dbw->lock( $lockKey, __METHOD__, 1 ) // 1 sec timeout
+ ) {
+ $this->doUpdatePendingDeltas();
+ return;
}
+ $pd = $this->getPendingDeltas();
+ // Piggy-back the async deltas onto those of this stats update....
+ $this->views += ( $pd['ss_total_views']['+'] - $pd['ss_total_views']['-'] );
+ $this->edits += ( $pd['ss_total_edits']['+'] - $pd['ss_total_edits']['-'] );
+ $this->articles += ( $pd['ss_good_articles']['+'] - $pd['ss_good_articles']['-'] );
+ $this->pages += ( $pd['ss_total_pages']['+'] - $pd['ss_total_pages']['-'] );
+ $this->users += ( $pd['ss_users']['+'] - $pd['ss_users']['-'] );
+ $this->images += ( $pd['ss_images']['+'] - $pd['ss_images']['-'] );
+ }
+
+ // Build up an SQL query of deltas and apply them...
+ $updates = '';
+ $this->appendUpdate( $updates, 'ss_total_views', $this->views );
+ $this->appendUpdate( $updates, 'ss_total_edits', $this->edits );
+ $this->appendUpdate( $updates, 'ss_good_articles', $this->articles );
+ $this->appendUpdate( $updates, 'ss_total_pages', $this->pages );
+ $this->appendUpdate( $updates, 'ss_users', $this->users );
+ $this->appendUpdate( $updates, 'ss_images', $this->images );
+ if ( $updates != '' ) {
+ $dbw->update( 'site_stats', array( $updates ), array(), __METHOD__ );
+ }
- $dbw->commit( __METHOD__ );
+ if ( $wgSiteStatsAsyncFactor ) {
+ // Decrement the async deltas now that we applied them
+ $this->removePendingDeltas( $pd );
+ // Commit the updates and unlock the table
+ $dbw->unlock( $lockKey, __METHOD__ );
}
}