* @author Aaron Schulz
* @ingroup JobQueue
*/
+use MediaWiki\MediaWikiServices;
/**
* Job for pruning recent changes
return; // already in progress
}
- $factory = wfGetLBFactory();
+ $factory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
$ticket = $factory->getEmptyTransactionTicket( __METHOD__ );
$cutoff = $dbw->timestamp( time() - $wgRCMaxAge );
do {
$dbw = wfGetDB( DB_MASTER );
// JobRunner uses DBO_TRX, but doesn't call begin/commit itself;
// onTransactionIdle() will run immediately since there is no trx.
- $dbw->onTransactionIdle( function() use ( $dbw, $days, $window ) {
- $factory = wfGetLBFactory();
- $ticket = $factory->getEmptyTransactionTicket( __METHOD__ );
- // Avoid disconnect/ping() cycle that makes locks fall off
- $dbw->setSessionOptions( [ 'connTimeout' => 900 ] );
-
- $lockKey = wfWikiID() . '-activeusers';
- if ( !$dbw->lock( $lockKey, __METHOD__, 1 ) ) {
- return; // exclusive update (avoids duplicate entries)
- }
-
- $nowUnix = time();
- // Get the last-updated timestamp for the cache
- $cTime = $dbw->selectField( 'querycache_info',
- 'qci_timestamp',
- [ 'qci_type' => 'activeusers' ]
- );
- $cTimeUnix = $cTime ? wfTimestamp( TS_UNIX, $cTime ) : 1;
-
- // Pick the date range to fetch from. This is normally from the last
- // update to till the present time, but has a limited window for sanity.
- // If the window is limited, multiple runs are need to fully populate it.
- $sTimestamp = max( $cTimeUnix, $nowUnix - $days * 86400 );
- $eTimestamp = min( $sTimestamp + $window, $nowUnix );
-
- // Get all the users active since the last update
- $res = $dbw->select(
- [ 'recentchanges' ],
- [ 'rc_user_text', 'lastedittime' => 'MAX(rc_timestamp)' ],
- [
- 'rc_user > 0', // actual accounts
- 'rc_type != ' . $dbw->addQuotes( RC_EXTERNAL ), // no wikidata
- 'rc_log_type IS NULL OR rc_log_type != ' . $dbw->addQuotes( 'newusers' ),
- 'rc_timestamp >= ' . $dbw->addQuotes( $dbw->timestamp( $sTimestamp ) ),
- 'rc_timestamp <= ' . $dbw->addQuotes( $dbw->timestamp( $eTimestamp ) )
- ],
- __METHOD__,
- [
- 'GROUP BY' => [ 'rc_user_text' ],
- 'ORDER BY' => 'NULL' // avoid filesort
- ]
- );
- $names = [];
- foreach ( $res as $row ) {
- $names[$row->rc_user_text] = $row->lastedittime;
- }
-
- // Rotate out users that have not edited in too long (according to old data set)
- $dbw->delete( 'querycachetwo',
- [
- 'qcc_type' => 'activeusers',
- 'qcc_value < ' . $dbw->addQuotes( $nowUnix - $days * 86400 ) // TS_UNIX
- ],
- __METHOD__
- );
+ $dbw->onTransactionIdle(
+ function () use ( $dbw, $days, $window ) {
+ $factory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+ $ticket = $factory->getEmptyTransactionTicket( __METHOD__ );
+ // Avoid disconnect/ping() cycle that makes locks fall off
+ $dbw->setSessionOptions( [ 'connTimeout' => 900 ] );
+
+ $lockKey = wfWikiID() . '-activeusers';
+ if ( !$dbw->lock( $lockKey, __METHOD__, 1 ) ) {
+ return; // exclusive update (avoids duplicate entries)
+ }
- // Find which of the recently active users are already accounted for
- if ( count( $names ) ) {
- $res = $dbw->select( 'querycachetwo',
- [ 'user_name' => 'qcc_title' ],
+ $nowUnix = time();
+ // Get the last-updated timestamp for the cache
+ $cTime = $dbw->selectField( 'querycache_info',
+ 'qci_timestamp',
+ [ 'qci_type' => 'activeusers' ]
+ );
+ $cTimeUnix = $cTime ? wfTimestamp( TS_UNIX, $cTime ) : 1;
+
+ // Pick the date range to fetch from. This is normally from the last
+ // update to till the present time, but has a limited window for sanity.
+ // If the window is limited, multiple runs are need to fully populate it.
+ $sTimestamp = max( $cTimeUnix, $nowUnix - $days * 86400 );
+ $eTimestamp = min( $sTimestamp + $window, $nowUnix );
+
+ // Get all the users active since the last update
+ $res = $dbw->select(
+ [ 'recentchanges' ],
+ [ 'rc_user_text', 'lastedittime' => 'MAX(rc_timestamp)' ],
[
- 'qcc_type' => 'activeusers',
- 'qcc_namespace' => NS_USER,
- 'qcc_title' => array_keys( $names ) ],
- __METHOD__
+ 'rc_user > 0', // actual accounts
+ 'rc_type != ' . $dbw->addQuotes( RC_EXTERNAL ), // no wikidata
+ 'rc_log_type IS NULL OR rc_log_type != ' . $dbw->addQuotes( 'newusers' ),
+ 'rc_timestamp >= ' . $dbw->addQuotes( $dbw->timestamp( $sTimestamp ) ),
+ 'rc_timestamp <= ' . $dbw->addQuotes( $dbw->timestamp( $eTimestamp ) )
+ ],
+ __METHOD__,
+ [
+ 'GROUP BY' => [ 'rc_user_text' ],
+ 'ORDER BY' => 'NULL' // avoid filesort
+ ]
);
+ $names = [];
foreach ( $res as $row ) {
- unset( $names[$row->user_name] );
+ $names[$row->rc_user_text] = $row->lastedittime;
}
- }
- // Insert the users that need to be added to the list
- if ( count( $names ) ) {
- $newRows = [];
- foreach ( $names as $name => $lastEditTime ) {
- $newRows[] = [
+ // Rotate out users that have not edited in too long (according to old data set)
+ $dbw->delete( 'querycachetwo',
+ [
'qcc_type' => 'activeusers',
- 'qcc_namespace' => NS_USER,
- 'qcc_title' => $name,
- 'qcc_value' => wfTimestamp( TS_UNIX, $lastEditTime ),
- 'qcc_namespacetwo' => 0, // unused
- 'qcc_titletwo' => '' // unused
- ];
+ 'qcc_value < ' . $dbw->addQuotes( $nowUnix - $days * 86400 ) // TS_UNIX
+ ],
+ __METHOD__
+ );
+
+ // Find which of the recently active users are already accounted for
+ if ( count( $names ) ) {
+ $res = $dbw->select( 'querycachetwo',
+ [ 'user_name' => 'qcc_title' ],
+ [
+ 'qcc_type' => 'activeusers',
+ 'qcc_namespace' => NS_USER,
+ 'qcc_title' => array_keys( $names ) ],
+ __METHOD__
+ );
+ foreach ( $res as $row ) {
+ unset( $names[$row->user_name] );
+ }
}
- foreach ( array_chunk( $newRows, 500 ) as $rowBatch ) {
- $dbw->insert( 'querycachetwo', $rowBatch, __METHOD__ );
- $factory->commitAndWaitForReplication( __METHOD__, $ticket );
+
+ // Insert the users that need to be added to the list
+ if ( count( $names ) ) {
+ $newRows = [];
+ foreach ( $names as $name => $lastEditTime ) {
+ $newRows[] = [
+ 'qcc_type' => 'activeusers',
+ 'qcc_namespace' => NS_USER,
+ 'qcc_title' => $name,
+ 'qcc_value' => wfTimestamp( TS_UNIX, $lastEditTime ),
+ 'qcc_namespacetwo' => 0, // unused
+ 'qcc_titletwo' => '' // unused
+ ];
+ }
+ foreach ( array_chunk( $newRows, 500 ) as $rowBatch ) {
+ $dbw->insert( 'querycachetwo', $rowBatch, __METHOD__ );
+ $factory->commitAndWaitForReplication( __METHOD__, $ticket );
+ }
}
- }
- // If a transaction was already started, it might have an old
- // snapshot, so kludge the timestamp range back as needed.
- $asOfTimestamp = min( $eTimestamp, (int)$dbw->trxTimestamp() );
+ // If a transaction was already started, it might have an old
+ // snapshot, so kludge the timestamp range back as needed.
+ $asOfTimestamp = min( $eTimestamp, (int)$dbw->trxTimestamp() );
- // Touch the data freshness timestamp
- $dbw->replace( 'querycache_info',
- [ 'qci_type' ],
- [ 'qci_type' => 'activeusers',
- 'qci_timestamp' => $dbw->timestamp( $asOfTimestamp ) ], // not always $now
- __METHOD__
- );
+ // Touch the data freshness timestamp
+ $dbw->replace( 'querycache_info',
+ [ 'qci_type' ],
+ [ 'qci_type' => 'activeusers',
+ 'qci_timestamp' => $dbw->timestamp( $asOfTimestamp ) ], // not always $now
+ __METHOD__
+ );
- $dbw->unlock( $lockKey, __METHOD__ );
- } );
+ $dbw->unlock( $lockKey, __METHOD__ );
+ },
+ __METHOD__
+ );
}
}