75 $rcMaxAge = $services->getMainConfig()->get(
77 $updateRowsPerQuery = $services->getMainConfig()->get(
79 $dbProvider = $services->getConnectionProvider();
80 $dbw = $dbProvider->getPrimaryDatabase();
81 $lockKey = $dbw->getDomainID() .
':recentchanges-prune';
82 if ( !$dbw->lock( $lockKey, __METHOD__, 0 ) ) {
86 $ticket = $dbProvider->getEmptyTransactionTicket( __METHOD__ );
87 $hookContainer = $services->getHookContainer();
88 $hookRunner =
new HookRunner( $hookContainer );
89 $cutoff = $dbw->timestamp( ConvertibleTimestamp::time() - $rcMaxAge );
90 $hasLegacyHook = $hookContainer->isRegistered(
'RecentChangesPurgeRows' );
91 if ( $hasLegacyHook ) {
92 $query = $dbw->newSelectQueryBuilder()
94 ->where( $dbw->expr(
'rc_timestamp',
'<', $cutoff ) )
95 ->limit( $updateRowsPerQuery )
96 ->caller( __METHOD__ );
98 $query = $dbw->newSelectQueryBuilder()
100 ->from(
'recentchanges' )
101 ->where( $dbw->expr(
'rc_timestamp',
'<', $cutoff ) )
102 ->limit( $updateRowsPerQuery )
103 ->caller( __METHOD__ );
106 $hookRunner->onRecentChangesPurgeQuery( $query, $callbacks );
108 $res = $query->fetchResultSet();
110 if ( $res->numRows() ) {
112 foreach ( $res as $row ) {
113 $rcIds[] = $row->rc_id;
114 if ( $hasLegacyHook ) {
119 $dbw->newDeleteQueryBuilder()
120 ->deleteFrom(
'recentchanges' )
121 ->where( [
'rc_id' => $rcIds ] )
122 ->caller( __METHOD__ )->execute();
124 foreach ( $callbacks as $callback ) {
127 if ( $hasLegacyHook ) {
128 $hookRunner->onRecentChangesPurgeRows( $rows );
131 if ( !$dbProvider->commitAndWaitForReplication(
132 __METHOD__, $ticket, [
'timeout' => 3 ]
140 $dbw->unlock( $lockKey, __METHOD__ );
145 $activeUserDays = $services->getMainConfig()->get(
149 $days = $activeUserDays;
151 $window = $activeUserDays * 86400;
153 $rcLookup = $services->getRecentChangeLookup();
154 $dbProvider = $services->getConnectionProvider();
155 $dbw = $dbProvider->getPrimaryDatabase();
156 $ticket = $dbProvider->getEmptyTransactionTicket( __METHOD__ );
158 $lockKey = $dbw->getDomainID() .
'-activeusers';
159 if ( !$dbw->lock( $lockKey, __METHOD__, 0 ) ) {
166 $dbw->setSessionOptions( [
'connTimeout' => 900 ] );
170 $cTime = $dbw->newSelectQueryBuilder()
171 ->select(
'qci_timestamp' )
172 ->from(
'querycache_info' )
173 ->where( [
'qci_type' =>
'activeusers' ] )
174 ->caller( __METHOD__ )->fetchField();
175 $cTimeUnix = $cTime ? (int)
wfTimestamp( TS::UNIX, $cTime ) : 1;
180 $sTimestamp = max( $cTimeUnix, $nowUnix - $days * 86400 );
181 $eTimestamp = min( $sTimestamp + $window, $nowUnix );
184 $res = $dbw->newSelectQueryBuilder()
185 ->select( [
'actor_name',
'lastedittime' =>
'MAX(rc_timestamp)' ] )
186 ->from(
'recentchanges' )
187 ->join(
'actor',
null,
'actor_id=rc_actor' )
189 $dbw->expr(
'actor_user',
'!=',
null ),
190 $dbw->expr(
'rc_source',
'=', $rcLookup->getPrimarySources() ),
191 $dbw->expr(
'rc_log_type',
'=',
null )->or(
'rc_log_type',
'!=',
'newusers' ),
192 $dbw->expr(
'rc_timestamp',
'>=', $dbw->timestamp( $sTimestamp ) ),
193 $dbw->expr(
'rc_timestamp',
'<=', $dbw->timestamp( $eTimestamp ) ),
195 ->groupBy(
'actor_name' )
197 ->caller( __METHOD__ )->fetchResultSet();
200 foreach ( $res as $row ) {
201 $names[$row->actor_name] = $row->lastedittime;
205 if ( count( $names ) ) {
206 $res = $dbw->newSelectQueryBuilder()
207 ->select( [
'user_name' =>
'qcc_title' ] )
208 ->from(
'querycachetwo' )
210 'qcc_type' =>
'activeusers',
212 'qcc_title' => array_map(
'strval', array_keys( $names ) ),
213 $dbw->expr(
'qcc_value',
'>=', $nowUnix - $days * 86400 ),
215 ->caller( __METHOD__ )->fetchResultSet();
218 foreach ( $res as $row ) {
219 unset( $names[$row->user_name] );
224 if ( count( $names ) ) {
226 foreach ( $names as $name => $lastEditTime ) {
228 'qcc_type' =>
'activeusers',
230 'qcc_title' => $name,
231 'qcc_value' => (int)
wfTimestamp( TS::UNIX, $lastEditTime ),
232 'qcc_namespacetwo' => 0,
236 foreach ( array_chunk( $newRows, 500 ) as $rowBatch ) {
237 $dbw->newInsertQueryBuilder()
238 ->insertInto(
'querycachetwo' )
240 ->caller( __METHOD__ )->execute();
241 $dbProvider->commitAndWaitForReplication( __METHOD__, $ticket );
247 $asOfTimestamp = min( $eTimestamp, (
int)$dbw->trxTimestamp() );
250 $dbw->newReplaceQueryBuilder()
251 ->replaceInto(
'querycache_info' )
253 'qci_type' =>
'activeusers',
254 'qci_timestamp' => $dbw->timestamp( $asOfTimestamp ),
256 ->uniqueIndexFields( [
'qci_type' ] )
257 ->caller( __METHOD__ )->execute();
260 $dbw->newDeleteQueryBuilder()
261 ->deleteFrom(
'querycachetwo' )
263 'qcc_type' =>
'activeusers',
264 $dbw->expr(
'qcc_value',
'<', $nowUnix - $days * 86400 )
266 ->caller( __METHOD__ )->execute();
269 SiteStatsUpdate::cacheUpdate( $dbw );
272 $dbw->unlock( $lockKey, __METHOD__ );