removeDuplicates = true; } /** * @return RecentChangesUpdateJob */ final public static function newPurgeJob() { return new self( SpecialPage::getTitleFor( 'Recentchanges' ), array( 'type' => 'purge' ) ); } public function run() { if ( $this->params['type'] === 'purge' ) { $this->purgeExpiredRows(); } else { throw new Exception( "Invalid 'type' parameter '{$this->params['type']}'." ); } return true; } protected function purgeExpiredRows() { global $wgRCMaxAge; $lockKey = wfWikiID() . ':recentchanges-prune'; $dbw = wfGetDB( DB_MASTER ); if ( !$dbw->lock( $lockKey, __METHOD__, 1 ) ) { return; // already in progress } $batchSize = 100; // Avoid slave lag $cutoff = $dbw->timestamp( time() - $wgRCMaxAge ); do { $rcIds = $dbw->selectFieldValues( 'recentchanges', 'rc_id', array( 'rc_timestamp < ' . $dbw->addQuotes( $cutoff ) ), __METHOD__, array( 'LIMIT' => $batchSize ) ); if ( $rcIds ) { $dbw->delete( 'recentchanges', array( 'rc_id' => $rcIds ), __METHOD__ ); } // No need for this to be in a transaction. $dbw->commit( __METHOD__, 'flush' ); if ( count( $rcIds ) === $batchSize ) { // There might be more, so try waiting for slaves if ( !wfWaitForSlaves( null, false, false, /* $timeout = */ 3 ) ) { // Another job will continue anyway break; } } } while ( $rcIds ); $dbw->unlock( $lockKey, __METHOD__ ); } }